home *** CD-ROM | disk | FTP | other *** search
/ The World of Computer Software / The World of Computer Software.iso / faq-s.zip / PROTOCOL.PAS < prev    next >
Pascal/Delphi Source File  |  1991-05-04  |  76KB  |  2,396 lines

  1. {$R-,S-,I-,D-,F+,V-,B-,N-,L+}
  2. {$M 65500,0,0 }
  3.  
  4. unit protocol;
  5.  
  6. interface
  7.  
  8. uses dos,crt,video,
  9.      configrt,gentypes,modem,statret,windows,gensubs,subs1,subs2,mainr2,
  10.      userret;
  11.  
  12. type btchuparray=array [1..100] of mstr;
  13.  
  14. var totaltime      :sstr;
  15.     cn             :byte;
  16.     bat2           :string;
  17.     mins           :integer;
  18.     status         :word;
  19.     curarea        :integer;
  20.     totpoints      :word;
  21.     xtype          :char;
  22.     a              :arearec;
  23.     protrec        :protorec;
  24.  
  25. procedure wipedszlog;
  26. procedure laterdays;
  27. procedure runext (var ret_code:integer; var commandline,switchz:lstr);
  28. function doext(mode,proto:char; uddir,fn:lstr; baud,comm:integer):integer;
  29. procedure beepbeep (ok:integer);
  30. function checkdszlog (fnxfered:anystr):char;
  31. function sponsoron:boolean;
  32. procedure seekudfile (n:integer);
  33. procedure requestfile;
  34. function getfname (path:lstr; name:mstr):lstr;
  35. procedure possiblelzm (points:integer);
  36. function checkok (ud:udrec):boolean;
  37. function searchforfile (f:sstr):integer;
  38. procedure listfile (n:integer; extended:boolean);
  39. procedure listfiles (extended:boolean);
  40. function allowxfer:boolean;
  41. function numuds:integer;
  42. function nofiles:boolean;
  43. function getfilenum (t:mstr):integer;
  44. function numb:integer;
  45. function totalxfersize:longint;
  46. function totalxfertime:integer;
  47. procedure addtobatch (auto:integer);
  48. procedure downbatch;
  49. procedure upbatch;
  50. procedure listbatch;
  51. procedure clearbatch;
  52. procedure listprotocols (t:integer);
  53. procedure batchmenu;
  54. procedure askaboutbye;
  55. procedure showhisstats;
  56. function findprot(rors,prot:char):boolean;
  57. function cmdline (f:lstr):lstr;
  58. function switches (c,fn:lstr):lstr;
  59. procedure avrcps;
  60. procedure fchangemenu;
  61. procedure newscanmenu;
  62. procedure sponsormenu;
  63. procedure xfermenu;
  64.  
  65. implementation
  66.  
  67. function protocolxfer (send,crcmode,ymodem:boolean; fn:lstr):integer;
  68. { Return codes:  0=OK, 1=Cancelled within last three blocks, 2=Aborted }
  69.  
  70. {% ENDIF}
  71.  
  72.   const can=^X; ack=^F; nak=^U; soh=^A; stx=^B; eot=^D; crcstart='C';
  73.  
  74.   var timedout:boolean;
  75.  
  76.   function tenthseconds:integer;
  77.   var r:registers;
  78.   begin
  79.     r.ah:=$2c;
  80.     intr ($21,r);
  81.     tenthseconds:=(r.dh*10)+(r.dl div 10)
  82.   end;
  83.  
  84.   function fromnow (tenths:integer):integer;
  85.   begin
  86.     tenths:=tenthseconds+tenths;
  87.     if tenths>599 then tenths:=tenths-600;
  88.     fromnow:=tenths
  89.   end;
  90.  
  91.   function timeout (en:integer):boolean;
  92.   begin
  93.     timeout:=(en=tenthseconds) or hungupon
  94.   end;
  95.  
  96.   procedure clearmodemahead;
  97.   var k:char;
  98.   begin
  99.     while numchars>0 do k:=getchar
  100.   end;
  101.  
  102.   procedure wait (tenths:integer);
  103.   begin
  104.     tenths:=fromnow (tenths);
  105.     repeat until timeout (tenths) or hungupon
  106.   end;
  107.  
  108.   function waitchar (tenths:integer):char;
  109.   begin
  110.     waitchar:=#0;
  111.     tenths:=fromnow (tenths);
  112.     repeat
  113.       if numchars>0 then begin
  114.         waitchar:=getchar;
  115.         timedout:=false;
  116.         exit
  117.       end
  118.     until timeout (tenths) or hungupon;
  119.     timedout:=true
  120.   end;
  121.  
  122.   procedure computecrc (var block; blocksize:integer; var outcrc:word);
  123.   var cnt,c2:integer;
  124.       crc,b:word;
  125.       blk:array[1..1030] of byte absolute block;
  126.       willbecarry:boolean;
  127.   begin
  128.     crc:=0;
  129.     for cnt:=1 to blocksize do begin
  130.       b:=blk[cnt];
  131.       for c2:=1 to 8 do begin
  132.         willbecarry:=(crc and $8000)=$8000;
  133.         crc:=(crc shl 1) or (b shr 7);
  134.         b:=(b shl 1) and 255;
  135.         if willbecarry then crc:=crc xor $1021
  136.       end
  137.     end;
  138.     outcrc:=crc
  139.   end;
  140.  
  141. (****
  142.     inline (
  143.              $1E/                    {           PUSH  DS               }
  144.              $C5/$B6/block/          {           LDS   SI,[BP+block]    }
  145.              $8B/$96/blocksize/      {           MOV   DX,[BP+blocksize]}
  146.              $31/$DB/                {           XOR   BX,BX            }
  147.              $FC/                    {           CLD                    }
  148.              $AC/                    { Mainloop: LODSB                  }
  149.              $B9/$08/$00/            {           MOV   CX,0008          }
  150.              $D0/$E0/                { Byteloop: SHL   AL,1             }
  151.              $D1/$D3/                {           RCL   BX,1             }
  152.              $73/$04/                {           JNC   No_xor           }
  153.              $81/$F3/$21/$10/        {           XOR   BX,1021          }
  154.              $E2/$F4/                { No_xor:   LOOP  Byteloop         }
  155.              $4A/                    {           DEC   DX               }
  156.              $75/$ED/                {           JNZ   Mainloop         }
  157.              $89/$9E/crc/            {           MOV   [BP+crc],BX      }
  158.              $1F                     {           POP   DS               }
  159.            );
  160. ****)
  161.  
  162.   procedure computecksum (var data; blocksize:integer; var outcksum:byte);
  163.   var t:array [1..1024] of byte absolute data;
  164.       cnt,q:integer;
  165.   begin
  166.     q:=0;
  167.     for cnt:=1 to blocksize do q:=q+t[cnt];
  168.     outcksum:=q and 255
  169.   end;
  170.  
  171.   procedure showerrorstats (curblk,totalerrs,consec:integer);
  172.   var x:integer;
  173.       r:real;
  174.   begin
  175.     x:=wherex;
  176.     write (usr,totalerrs);
  177.     gotoxy (x,wherey+1);
  178.     write (usr,consec,' ');
  179.     gotoxy (x,wherey+1);
  180.     if curblk+totalerrs<>0 then begin
  181.       r:=round(10000.0*totalerrs/(curblk+totalerrs))/100.0;
  182.       write (usr,r:0:2,'%    ')
  183.     end
  184.   end;
  185.  
  186.   function xymodemsend (ymodem:boolean):integer;
  187.   var f:file;
  188.       b:array [1..1026] of byte;
  189.       blocksize:integer;
  190.       fsize,curblk,totalerrs,consec,blocksatatime:integer;
  191.       k:char;
  192.       firstblock:boolean;
  193.  
  194.     function getctrlchar:char;   { Gets ACK/NAK/CAN }
  195.     var k,k2:char;
  196.         cnt:integer;
  197.     begin
  198.       getctrlchar:=can;
  199.       repeat
  200.         cnt:=0;
  201.         repeat
  202.           k:=waitchar (10);
  203.           cnt:=cnt+1;
  204.           if keyhit then begin
  205.             k2:=bioskey;
  206.             if k2=^X then exit;
  207.             timedout:=true
  208.           end
  209.         until (not timedout) or (cnt=60);
  210.         if timedout or hungupon then exit;
  211.         if (k in [ack,nak,crcstart,can]) then begin
  212.           getctrlchar:=k;
  213.           if k=can then sendchar (can);
  214.           exit
  215.         end
  216.       until hungupon;
  217.       timedout:=true
  218.     end;
  219.  
  220.     procedure sendendoffile;
  221.     var k:char;
  222.         tries:integer;
  223.     begin
  224.       tries:=0;
  225.       repeat
  226.         tries:=tries+1;
  227.         sendchar(eot);
  228.         k:=waitchar (20);
  229.       until (k=ack) or (k=can) or (tries=3);
  230.       sendchar(eot)
  231.     end;
  232.  
  233.     procedure getblockfromfile;
  234.     begin
  235.       fillchar (b,sizeof(b),26);
  236.       blockread (f,b,blocksatatime);
  237.       blocksize:=blocksatatime shl 7
  238.     end;
  239.  
  240.     procedure buildfirstblock;
  241.     var cnt,p:integer;
  242.     begin
  243.       blocksize:=128;
  244.       fillchar(b,128,0);
  245.       p:=length(fn);
  246.       repeat
  247.         p:=p-1
  248.       until (p=0) or (fn[p]='\');
  249.       for cnt:=1 to length(fn)-p do b[cnt]:=ord(fn[cnt+p])
  250.     end;
  251.  
  252.     procedure sendblock (num:integer);
  253.     var cnt,bksize:integer;
  254.         crc:word;
  255.         n:byte;
  256.         k:char;
  257.     begin
  258.       clearmodemahead;
  259.       n:=num and 255;
  260.       if blocksize=1024
  261.         then k:=stx
  262.         else k:=soh;
  263.       if crcmode
  264.         then
  265.           begin
  266.             b[blocksize+1]:=0;
  267.             b[blocksize+2]:=0;
  268.             computecrc (b,blocksize+2,crc);
  269.             b[blocksize+1]:=hi(crc);
  270.             b[blocksize+2]:=lo(crc);
  271.             bksize:=blocksize+2;
  272.           end
  273.         else
  274.           begin
  275.             b[blocksize+1]:=0;
  276.             computecksum (b,blocksize,b[blocksize+1]);
  277.             bksize:=blocksize+1
  278.           end;
  279.       sendchar (k);
  280.       sendchar (chr(n));
  281.       sendchar (chr(255-n));
  282.       for cnt:=1 to bksize do sendchar(chr(b[cnt]))
  283.     end;
  284.  
  285.     procedure updatestatus;
  286.     begin
  287.       gotoxy (16,3);
  288.       write (usr,curblk,' of ',fsize);
  289.       gotoxy (16,4);
  290.       write (usr,minstr((fsize-curblk)*blocksatatime),' of ',totaltime,' ');
  291.       gotoxy (16,5);
  292.       showerrorstats (curblk,totalerrs,consec)
  293.     end;
  294.  
  295.     procedure initxfer;
  296.     begin
  297.       starttimer (numminsxfer);
  298.       if ymodem then blocksatatime:=8 else blocksatatime:=1;
  299.       fsize:=(filesize(f)+blocksatatime-1) div blocksatatime;
  300.       totaltime:=minstr(fsize*blocksatatime);
  301.       totalerrs:=0;
  302.       consec:=0;
  303.       firstblock:=true;
  304.       if ymodem
  305.         then
  306.           begin
  307.             curblk:=0;
  308.             buildfirstblock
  309.           end
  310.         else
  311.           begin
  312.             curblk:=1;
  313.             getblockfromfile
  314.           end;
  315.       splitscreen (8);
  316.       top;
  317.       write (usr,'Waiting for NAK')
  318.     end;
  319.  
  320.     procedure setupscreen;
  321.     begin
  322.       gotoxy (1,1);
  323.       if ymodem then write (usr,'Y') else write (usr,'X');
  324.       write (usr,'modem');
  325.       if crcmode then write (usr,'-CRC');
  326.       writeln (usr,' send in progress.  Press [Ctrl-X] to Abort.');
  327.       clreol;
  328.       gotoxy (1,3);
  329.       writeln (usr,'Current block:');
  330.       writeln (usr,'Time left:');
  331.       writeln (usr,'Total errors:');
  332.       writeln (usr,'  Consecutive:');
  333.       write (usr,'Error rate:')
  334.     end;
  335.  
  336.   label abort,done;
  337.   begin
  338.     xymodemsend:=2;
  339.     assign (f,fn);
  340.     reset (f);
  341.     iocode:=ioresult;
  342.     if iocode<>0 then exit;
  343.     initxfer;
  344.     repeat
  345.       k:=getctrlchar;
  346.       if k=can then begin
  347.         if (curblk>(fsize*3/4)) and (curblk>2)
  348.           then xymodemsend:=1; { Cheater! }
  349.         goto abort
  350.       end;
  351.       if firstblock then begin
  352.         if (k=nak) or (k=crcstart) then firstblock:=false;
  353.         crcmode:=k=crcstart;
  354.         setupscreen;
  355.         k:=#0
  356.       end;
  357.       if k=ack then begin
  358.         curblk:=curblk+1;
  359.         if eof(f) then goto done;
  360.         getblockfromfile
  361.       end;
  362.       if k<>nak then consec:=0 else begin
  363.         totalerrs:=totalerrs+1;
  364.         consec:=consec+1
  365.       end;
  366.       sendblock(curblk);
  367.       updatestatus
  368.     until 0=1;
  369.     done:
  370.     sendendoffile;
  371.     xymodemsend:=0;
  372.     abort:
  373.     close (f);
  374.     unsplit;
  375.     stoptimer (numminsxfer)
  376.   end;
  377.  
  378.   function xymodemreceive(ymodem:boolean):integer;
  379.   var f:file;
  380.       block:array [1..1026] of byte;
  381.       blkl,blkh,xblkl,nblkl,nblk1:byte;
  382.       curblk:integer;
  383.       ctrl,k,k2:char;
  384.       timeul,consec,totalerrs,blocksize:integer;
  385.       canceled,timeout:boolean;
  386.  
  387.     procedure cancel;
  388.     begin
  389.       wait (10);
  390.       clearmodemahead;
  391.       sendchar (can);
  392.       wait (10);
  393.       clearmodemahead;
  394.       sendchar (can);
  395.       canceled:=true
  396.     end;
  397.  
  398.     function writeblock:boolean;
  399.     var wb:boolean;
  400.     begin
  401.       blockwrite (f,block,blocksize div 128);
  402.       wb:=ioresult=0;
  403.       writeblock:=wb;
  404.       if not wb then begin
  405.         gotoxy (1,1);
  406.         write (usr,'I/O ERROR ',iocode,' WRITING BLOCK');
  407.         clreol;
  408.         sendchar (can);
  409.         wait (10);
  410.         sendchar (can);
  411.         clearmodemahead
  412.       end
  413.     end;
  414.  
  415.     procedure updatestatus;
  416.     begin
  417.       curblk:=blkl+(blkh shl 8);
  418.       gotoxy (16,3);
  419.       write (usr,curblk);
  420.       gotoxy (16,4);
  421.       showerrorstats (curblk,totalerrs,consec)
  422.     end;
  423.  
  424.     function sendctrl:char;
  425.     var cnt,consec:integer;
  426.         k:char;
  427.     begin
  428.       cnt:=0;
  429.       consec:=0;
  430.       timeout:=false;
  431.       updatestatus;
  432.       sendctrl:=can;
  433.       repeat
  434.         if keyhit then begin
  435.           k:=bioskey;
  436.           if k=^X then begin
  437.             timeout:=true;
  438.             cancel;
  439.             exit
  440.           end
  441.         end;
  442.         sendctrl:=waitchar (50);
  443.         if not timedout then exit;
  444.         sendchar (ctrl);
  445.         cnt:=0;
  446.         consec:=consec+1
  447.       until (consec=10) or hungupon;
  448.       timeout:=true
  449.     end;
  450.  
  451.     function getachar:char;
  452.     var cnt:integer;
  453.         k:char;
  454.     begin
  455.       getachar:=#0;
  456.       timeout:=timeout or hungupon;
  457.       if timeout then exit;
  458.       timeout:=false;
  459.       if keyhit then begin
  460.         k:=bioskey;
  461.         if k=^X then begin
  462.           getachar:=#0;
  463.           timeout:=true;
  464.           cancel;
  465.           exit
  466.         end
  467.       end;
  468.       getachar:=waitchar (10);
  469.       timeout:=timeout or timedout
  470.     end;
  471.  
  472.     procedure xfererror (txt:lstr);
  473.     begin
  474.       gotoxy (16,7);
  475.       write (usr,txt,' in block ',curblk);
  476.       clreol
  477.     end;
  478.  
  479.     procedure initxfer;
  480.     var k:char;
  481.     begin
  482.       timeul:=timer;
  483.       timeout:=false;
  484.       consec:=0;
  485.       blkl:=1;
  486.       blkh:=0;
  487.       xblkl:=1;
  488.       curblk:=1;
  489.       totalerrs:=0;
  490.       if crcmode
  491.         then ctrl:=crcstart
  492.         else ctrl:=nak;
  493.       canceled:=false;
  494.       starttimer (numminsxfer);
  495.       splitscreen (8);
  496.       top;
  497.       gotoxy (1,1);
  498.       if ymodem then write (usr,'Y') else write (usr,'X');
  499.       write (usr,'modem');
  500.       if crcmode then write (usr,'-CRC');
  501.       write (usr,' receive in progress.  Press [Ctrl-X] to Abort.'^M^J^J,
  502.              'Current block:'^M^J,
  503.              'Total errors:'^M^J,
  504.              '  Consecutive:'^M^J,
  505.              'Error rate:'^M^J,
  506.              'Error type:');
  507.       while numchars>0 do k:=getchar
  508.     end;
  509.  
  510.     procedure endoffile;
  511.     begin
  512.       xymodemreceive:=0;
  513.       sendchar (ack);
  514.       wait (10);
  515.       sendchar (ack);
  516.       clearmodemahead
  517.     end;
  518.  
  519.     function block0:boolean;
  520.     var b0:boolean;
  521.         cnt:integer;
  522.     begin
  523.       b0:=(nblkl=0) and (nblk1=255) and (blkh=0) and (blkl<>255);
  524.       if b0 then begin
  525.         xfererror ('(Receiving block 0...)');
  526.         for cnt:=1 to blocksize do block[cnt]:=ord(getachar);
  527.         ctrl:=ack;
  528.         sendchar (ack)
  529.       end;
  530.       block0:=b0
  531.     end;
  532.  
  533.     function blocknumerror:boolean;
  534.     var bne:boolean;
  535.     begin
  536.       bne:=(nblkl<>(255-nblk1)) or ((nblkl<>xblkl) and (nblkl<>blkl));
  537.       if bne then xfererror ('Block # '+strr(nblkl)+' not '+strr(255-nblk1)+
  538.                              ' and '+strr(xblkl)+' or '+strr(blkl));
  539.       blocknumerror:=bne
  540.     end;
  541.  
  542.     function resentnoreason:boolean;
  543.     var rnr:boolean;
  544.         cnt:integer;
  545.     begin
  546.       rnr:=(nblkl<>xblkl) and (nblkl=blkl);
  547.       if rnr then begin
  548.         xfererror ('Block re-sent for no reason');
  549.         for cnt:=1 to blocksize do block[cnt]:=ord(getachar);
  550.         ctrl:=ack;
  551.         sendchar (ack)
  552.       end;
  553.       resentnoreason:=rnr
  554.     end;
  555.  
  556.     procedure getblockfrommodem;
  557.     var cnt:integer;
  558.     begin
  559.       for cnt:=1 to blocksize do begin
  560.         block[cnt]:=ord(getachar);
  561.         if timeout then exit
  562.       end
  563.     end;
  564.  
  565.     function badblock:boolean;
  566.     var crc:word;
  567.         cksum,reccksum:byte;
  568.     begin
  569.       badblock:=false;
  570.       if crcmode
  571.         then
  572.           begin
  573.             computecrc(block,blocksize,crc);
  574.             if crc<>0 then begin
  575.               xfererror ('CRC error');
  576.               badblock:=true
  577.             end
  578.           end
  579.         else
  580.           begin
  581.             reccksum:=block[129];
  582.             block[129]:=0;
  583.             computecksum(block,blocksize,cksum);
  584.             if cksum<>reccksum then begin
  585.               xfererror ('Checksum error');
  586.               badblock:=true
  587.             end
  588.           end
  589.     end;
  590.  
  591.   label nakit,abort,done;
  592.   begin
  593.     xymodemreceive:=2;
  594.     assign (f,fn);
  595.     rewrite (f);
  596.     iocode:=ioresult;
  597.     if iocode<>0 then begin
  598.       fileerror ('XYMODEMRECEIVE',fn);
  599.       exit
  600.     end;
  601.     initxfer;
  602.     repeat
  603.       k:=sendctrl;
  604.       ctrl:=nak;
  605.       if timeout or (k=can) then goto abort;
  606.       if k=eot then begin
  607.         endoffile;
  608.         goto done
  609.       end;
  610.       case k of
  611.         soh:blocksize:=128;
  612.         stx:blocksize:=1024
  613.         else begin
  614.           xfererror ('SOH error: '+strr(ord(k)));
  615.           goto nakit
  616.         end
  617.       end;
  618.       if crcmode
  619.         then blocksize:=blocksize+2
  620.         else blocksize:=blocksize+1;
  621.       nblkl:=ord(getachar);
  622.       nblk1:=ord(getachar);
  623.       if timeout then goto nakit;
  624.       if block0 then goto nakit;
  625.       if blocknumerror then goto nakit;
  626.       if resentnoreason then goto nakit;
  627.       if (nblkl=0) and (blkl=255) then blkh:=blkh+1;
  628.       blkl:=nblkl;
  629.       getblockfrommodem;
  630.       if timeout then goto nakit;
  631.       if badblock then goto nakit;
  632.       ctrl:=ack;
  633.       xblkl:=blkl+1;
  634.       sendchar (ack);
  635.       updatestatus;
  636.       if not writeblock then goto abort;
  637.       consec:=0;
  638.       nakit:
  639.       if hungupon then goto abort;
  640.       if timeout then xfererror ('Time out (short block)');
  641.       if ctrl<>ack then begin
  642.         totalerrs:=totalerrs+1;
  643.         consec:=consec+1;
  644.         repeat
  645.           k:=waitchar (10)
  646.         until timedout;
  647.         if consec>=15 then begin
  648.           sendchar (can);
  649.           goto abort
  650.         end;
  651.         sendchar (ctrl)
  652.       end
  653.     until 0=1;
  654.     abort:
  655.     cancel;
  656.     done:
  657.     close (f); consec:=ioresult;
  658.     if canceled then begin
  659.       erase (f); consec:=ioresult
  660.     end;
  661.     timeul:=timer-timeul;
  662.     if timeul<0 then timeul:=timeul+1440;
  663.     settimeleft (timeleft+timeul*2);
  664.     unsplit;
  665.     stoptimer (numminsxfer)
  666.   end;
  667.  
  668. begin
  669.   totaltime:='';
  670.   if send
  671.     then protocolxfer:=xymodemsend(ymodem)
  672.     else protocolxfer:=xymodemreceive(ymodem)
  673. end;
  674.  
  675.   procedure wipedszlog;
  676.   var ff:file of protorec;
  677.   begin
  678.     if exist(dszlogname) then begin
  679.                 assign(ff,dszlogname);
  680.                 erase(ff);
  681.                   end;
  682.   end;
  683.  
  684.  
  685.   function cmdline (f:lstr):lstr;
  686.   begin
  687.   cmdline:=faqdir+f;
  688.   end;
  689.  
  690.   function switches (c,fn:lstr):lstr;
  691.   var x,y,z,w:string;
  692.       a,s:integer;
  693.  
  694.   begin
  695.    s:=0;
  696.    x:='';
  697.    y:='';
  698.    z:='';
  699.    w:='';
  700.  
  701.    repeat
  702.       s:=s+1;
  703.       w:=w+c[s];
  704.    until c[s]=' ';
  705.    delete (c,1,s);
  706.  
  707.    for a:=1 to length(c) do begin
  708.          x:=copy (c,a,1);
  709.          if x='%' then begin
  710.                y:=copy (c,a+1,1);
  711.                 case valu(y) of
  712.                     1:z:=z+strr(usecom);
  713.                     2:z:=z+strr(baudrate);
  714.                     3:z:=z+fn;
  715.                                         4:z:=z+strr(urec.averagecps);
  716.                     end;
  717.                delete (c,a+1,1);
  718.                 end else z:=z+x;
  719.    end;
  720.    switches:=z;
  721.   end;
  722.  
  723.   procedure avrcps;
  724.   begin
  725.   urec.averagecps:=baudrate div 10;
  726.   writeln(^R'Average CPS: '^S,strr(urec.averagecps));
  727.   end;
  728.  
  729.   procedure showhisstats;
  730.   begin
  731.     writeln;
  732.     writeln(^R'NEW: Transfer Statistics:');
  733. if ascii then
  734.     writeln('────────────────────────────') else
  735.     writeln('----------------------------');
  736.  
  737. writeln(^R'Uploads:     '^S+strr(urec.uploads)+^R+' ['+^S+streal(urec.upk)+^R+' bytes]');
  738. writeln(^R'Downloads:   '^S+strr(urec.downloads)+^R+' ['+^S+streal(urec.downk)+^R+' bytes]');
  739. writeln(^R'File Points: '^S+strr(urec.udpoints)+^R);
  740. if useqr then begin
  741. calcqr;
  742. writeln(^R'Your QR:     '^S+strr(qr)+^R);
  743.           end;
  744.         avrcps;
  745.     writeln;
  746.   end;
  747.  
  748.  
  749.   procedure askaboutbye;
  750.   begin
  751.        writeln;
  752.   writestr(^S'H'^R'angup after batch  '^S'A'+
  753.   ^R'bort  '^S'C'^P'/'^S'R'^R' Start Transfer'^P': '^U'&');
  754.   if length(input)=0 then answer:='X' else answer:=upcase(input[1]);
  755.   writeln;
  756.   end;
  757.  
  758.  
  759.   procedure laterdays;
  760.   begin
  761.        write(^S+timestr(now)+^R' Logged off after transfer.');
  762.        forcehangup:=true;
  763.   end;
  764.  
  765.  
  766.   procedure runext (var ret_code:integer; var commandline,switchz:lstr);
  767.   begin
  768.    exec (commandline,switchz);
  769.    if doserror<>0 then
  770.     begin
  771.       writeln;
  772.       writeln (^G^G);
  773.       write ('DOS Error #',doserror,' - ');
  774.       case doserror of
  775.            2: writeln('File Not Found');
  776.            3: writeln('Path Not Found');
  777.            else writeln(' Unknown');
  778.            end;
  779.            writeln;
  780.       writeln ('Please report the error number to the Sysop!');
  781.       writeln;
  782. pause;
  783.     end
  784.    else ret_code:=dosexitcode;
  785.   end;
  786.  
  787.   function findprot(rors,prot:char):boolean;
  788.   var bonzo:file of protorec; sod:boolean;
  789.  
  790.   begin
  791.        sod:=false;
  792.        assign(bonzo,bbsdatadir+'PROT'+rors+'.CFG');
  793.        reset(bonzo);
  794.        while not(eof(bonzo)) and not(sod) do
  795.              begin
  796.                   read(bonzo,protrec);
  797.                   if protrec.letter=upcase(prot) then sod:=true;
  798.              end;
  799.        findprot:=sod;
  800.        prprog:=protrec.progname;
  801.        prcomm:=protrec.commfmt;
  802.        prdesc:=protrec.desc;
  803.        close(bonzo);
  804.   end;
  805.  
  806.   function checkwork:integer;
  807.   var r:registers;
  808.       ffinfo:searchrec;
  809.       tpath:anystr;
  810.       b:byte;
  811.       cnt:integer;
  812.   begin
  813.     { getdir (defaultdrive,tpath); }
  814.     tpath:=xferdir+'*.*'; cnt:=0;
  815.     findfirst (tpath,$17,ffinfo);
  816.  
  817. while doserror=0 do begin
  818.  
  819. if not break then if ffinfo.name[1]<>'.' then cnt:=cnt+1;
  820.       findnext (ffinfo)
  821.       end;
  822.     checkwork:=cnt;
  823.   end;
  824.  
  825.   function doext (mode,proto:char; uddir,fn:lstr; baud,comm:integer):integer;
  826.   var cline,switchz,dirsave,cddir,temp:lstr;
  827.       baudst,commst:mstr;
  828.       retcd:integer; mess:lstr;
  829.       foofur:text; rt:boolean;
  830.       i,h1,h2,m1,m2,s1,s2,ss1,ss2:word;
  831.       udr:real;
  832.  type ScreenType = array [0..3999] of Byte;
  833.   var ScreenAddr : ScreenType absolute $B800:$0000;
  834. const
  835.   IMAGEDATA_WIDTH=80;
  836.   IMAGEDATA_DEPTH=5;
  837.   IMAGEDATA_LENGTH=801;
  838.   IMAGEDATA : array [1..801] of Char = (#9  ,
  839.     '┌' ,#9  ,'─' ,#9  ,'─' ,#9  ,'─' ,#9  ,'─' ,#9  ,'─' ,#9  ,'─' ,#9  ,
  840.     '─' ,#9  ,'─' ,#9  ,'─' ,#9  ,'─' ,#9  ,'─' ,#9  ,'─' ,#9  ,'─' ,#9  ,
  841.     '─' ,#9  ,'─' ,#9  ,'─' ,#9  ,'─' ,#9  ,'─' ,#9  ,'─' ,#9  ,'─' ,#9  ,
  842.     '─' ,#9  ,'─' ,#9  ,'─' ,#9  ,'─' ,#9  ,'─' ,#9  ,'─' ,#9  ,'─' ,#9  ,
  843.     '─' ,#9  ,'─' ,#9  ,'─' ,#9  ,'─' ,#9  ,'─' ,#9  ,'─' ,#9  ,'─' ,#9  ,
  844.     '─' ,#9  ,'─' ,#9  ,'─' ,#9  ,'─' ,#9  ,'─' ,#9  ,'─' ,#9  ,'─' ,#9  ,
  845.     '─' ,#9  ,'─' ,#9  ,'─' ,#9  ,'─' ,#9  ,'─' ,#9  ,'─' ,#9  ,'─' ,#9  ,
  846.     '─' ,#9  ,'─' ,#9  ,'─' ,#9  ,'─' ,#9  ,'─' ,#9  ,'─' ,#9  ,'─' ,#9  ,
  847.     '─' ,#9  ,'─' ,#9  ,'─' ,#9  ,'─' ,#9  ,'─' ,#9  ,'─' ,#9  ,'─' ,#9  ,
  848.     '─' ,#9  ,'─' ,#9  ,'─' ,#9  ,'─' ,#9  ,'─' ,#9  ,'─' ,#9  ,'─' ,#9  ,
  849.     '─' ,#9  ,'─' ,#9  ,'─' ,#9  ,'─' ,#9  ,'─' ,#9  ,'─' ,#9  ,'─' ,#9  ,
  850.     '─' ,#9  ,'─' ,#9  ,'┐' ,#9  ,'│' ,#9  ,' ' ,#11 ,'F' ,#11 ,'i' ,#11 ,
  851.     'l' ,#11 ,'e' ,#11 ,'n' ,#11 ,'a' ,#11 ,'m' ,#11 ,'e' ,#9  ,':' ,#9  ,
  852.     ' ' ,#9  ,' ' ,#9  ,' ' ,#9  ,' ' ,#9  ,' ' ,#9  ,' ' ,#9  ,' ' ,#9  ,
  853.     ' ' ,#9  ,' ' ,#9  ,' ' ,#9  ,' ' ,#9  ,' ' ,#9  ,' ' ,#9  ,' ' ,#9  ,
  854.     ' ' ,#9  ,' ' ,#9  ,' ' ,#9  ,' ' ,#9  ,' ' ,#9  ,' ' ,#9  ,' ' ,#9  ,
  855.     ' ' ,#9  ,' ' ,#9  ,' ' ,#9  ,' ' ,#9  ,' ' ,#9  ,' ' ,#9  ,' ' ,#9  ,
  856.     ' ' ,#9  ,' ' ,#11  ,'P',#11 ,'r' ,#11 ,'o' ,#11 ,'t' ,#11 ,'o' ,#11 ,
  857.     'c' ,#11 ,'o' ,#11 ,'l' ,#9  ,':' ,#9  ,' ' ,#9  ,' ' ,#9  ,' ' ,#9  ,
  858.     ' ' ,#9  ,' ' ,#9  ,' ' ,#9  ,' ' ,#9  ,' ' ,#9  ,' ' ,#9  ,' ' ,#9  ,
  859.     ' ' ,#9  ,' ' ,#9  ,' ' ,#9  ,' ' ,#9  ,' ' ,#9  ,' ' ,#9  ,' ' ,#9  ,
  860.     ' ' ,#9  ,' ' ,#9  ,' ' ,#9  ,' ' ,#9  ,' ' ,#9  ,' ' ,#9  ,' ' ,#9  ,
  861.     ' ' ,#9  ,' ' ,#9  ,' ' ,#9  ,' ' ,#9  ,' ' ,#9  ,'│' ,#9  ,'│' ,#9  ,
  862.     ' ' ,#11 ,'#' ,#11 ,' ',#11 ,'o' ,#11 ,'f' ,#11 ,' '  ,#11 ,'U' ,#11 ,
  863.     '/' ,#11 ,'l' ,#11 ,'s' ,#9  ,':' ,#9  ,' ' ,#9  ,' ' ,#9  ,' ' ,#9  ,
  864.     ' ' ,#9  ,' ' ,#9  ,' ' ,#9  ,' ' ,#9  ,' ' ,#9  ,' ' ,#11 ,'#' ,#11 ,
  865.     ' ' ,#11 ,'o' ,#11 ,'f' ,#11 ,' ' ,#11 ,'D' ,#11 ,'/' ,#11 ,'l' ,#11 ,
  866.     's' ,#9  ,':' ,#9  ,' ' ,#9  ,' ' ,#9  ,' ' ,#9  ,' ' ,#9  ,' ' ,#9  ,
  867.     ' ' ,#9  ,' ' ,#9  ,' ' ,#9  ,' ' ,#9  ,' ' ,#11 ,'M' ,#11 ,'o' ,#11 ,
  868.     'd' ,#11 ,'e' ,#9  ,':' ,#9  ,' ' ,#9  ,' ' ,#9  ,' ' ,#9  ,' ' ,#9  ,
  869.     ' ' ,#9  ,' ' ,#9  ,' ' ,#9  ,' ' ,#9  ,' ' ,#9  ,' ' ,#9  ,' ' ,#9  ,
  870.     ' ' ,#9  ,' ' ,#9  ,' ' ,#9  ,' ' ,#9  ,' ' ,#9  ,' ' ,#9  ,' ' ,#9  ,
  871.     ' ' ,#9  ,' ' ,#9  ,' ' ,#9  ,' ' ,#9  ,' ' ,#9  ,' ' ,#9  ,' ' ,#9  ,
  872.     ' ' ,#9  ,' ' ,#9  ,' ' ,#9  ,' ' ,#9  ,' ' ,#9  ,' ' ,#9  ,' ' ,#9  ,
  873.     ' ' ,#9  ,'│' ,#9  ,'│' ,#9  ,' ' ,#11  ,'C' ,#11 ,'u' ,#11 ,'r' ,#11 ,
  874.     'r' ,#11 ,'e' ,#11 ,'n' ,#11 ,'t' ,#11 ,' ' ,#11 ,'U' ,#11 ,'s' ,#11 ,
  875.     'e' ,#11 ,'r' ,#9  ,':' ,#9  ,' ' ,#9  ,' ' ,#9  ,' ' ,#9  ,' ' ,#9  ,
  876.     ' ' ,#9  ,' ' ,#9  ,' ' ,#9  ,' ' ,#9  ,' ' ,#9  ,' ' ,#9  ,' ' ,#9  ,
  877.     ' ' ,#9  ,' ' ,#9  ,' ' ,#9  ,' ' ,#9  ,' ' ,#9  ,' ' ,#9  ,' ' ,#9  ,
  878.     ' ' ,#9  ,' ' ,#9  ,' ' ,#9  ,' ' ,#9  ,' ' ,#9  ,' ' ,#9  ,' ' ,#9  ,
  879.     ' ' ,#11  ,'F' ,#11 ,'i' ,#11 ,'l' ,#11 ,'e',#11 ,' ' ,#11 ,'P' ,#11 ,
  880.     'o' ,#11 ,'i' ,#11 ,'n' ,#11 ,'t' ,#11 ,'s' ,#9  ,':' ,#9  ,' ' ,#9  ,
  881.     ' ' ,#9  ,' ' ,#9  ,' ' ,#9  ,' ' ,#9  ,' ' ,#9  ,' ' ,#9  ,' ' ,#9  ,
  882.     ' ' ,#9  ,' ' ,#9  ,' ' ,#9  ,' ' ,#9  ,' ' ,#9  ,' ' ,#9  ,' ' ,#9  ,
  883.     ' ' ,#9  ,' ' ,#9  ,' ' ,#9  ,' ' ,#9  ,' ' ,#9  ,' ' ,#9  ,' ' ,#9  ,
  884.     ' ' ,#9  ,' ' ,#9  ,' ' ,#9  ,' ' ,#9  ,'│' ,#9  ,'└' ,#9  ,'─' ,#9  ,
  885.     '─' ,#9  ,'─' ,#9  ,'─' ,#9  ,'─' ,#9  ,'─' ,#9  ,'─' ,#9  ,'─' ,#9  ,
  886.     '─' ,#9  ,'─' ,#9  ,'─' ,#9  ,'─' ,#9  ,'─' ,#9  ,'─' ,#9  ,'─' ,#9  ,
  887.     '─' ,#9  ,'─' ,#9  ,'─' ,#9  ,'─' ,#9  ,'─' ,#9  ,'─' ,#9  ,'─' ,#9  ,
  888.     '─' ,#9  ,'─' ,#9  ,'─' ,#9  ,'─' ,#9  ,'─' ,#9  ,'─' ,#9  ,'─' ,#9  ,
  889.     '─' ,#9  ,'─' ,#9  ,'─' ,#9  ,'─' ,#9  ,'─' ,#9  ,'─' ,#9  ,'─' ,#9  ,
  890.     '─' ,#9  ,'─' ,#9  ,'─' ,#9  ,'─' ,#9  ,'─' ,#9  ,'─' ,#9  ,'─' ,#9  ,
  891.     '─' ,#9  ,'─' ,#9  ,'─' ,#9  ,'─' ,#9  ,'─' ,#9  ,'─' ,#9  ,'─' ,#9  ,
  892.     '─' ,#9  ,'─' ,#9  ,'─' ,#9  ,'─' ,#9  ,'─' ,#9  ,'─' ,#9  ,'─' ,#9  ,
  893.     '─' ,#9  ,'─' ,#9  ,'─' ,#9  ,'─' ,#9  ,'─' ,#9  ,'─' ,#9  ,'─' ,#9  ,
  894.     '─' ,#9  ,'─' ,#9  ,'─' ,#9  ,'─' ,#9  ,'─' ,#9  ,'─' ,#9  ,'─' ,#9  ,
  895.     '─' ,#9  ,'─' ,#9  ,'─' ,#9  ,'─' ,#9  ,'─' ,#9  ,'─' ,#9  ,'─' ,#9  ,
  896.     '┘' ,#9  );
  897.  
  898. procedure UNCRUNCH (var Addr1,Addr2; BlkLen:Integer);
  899. begin
  900.   inline (
  901. $1E/$C5/$B6/Addr1/$C4/$BE/Addr2/$8B/$8E/BlkLen/$8B/$D7/$33/$C0/
  902. $FC/$AC/$3C/$1B/$75/$05/$80/$F4/$80/$EB/$4D/$3C/$10/$73/$07/
  903. $80/$E4/$70/$0A/$E0/$EB/$42/$3C/$18/$74/$13/$73/$19/$2C/$10/
  904. $02/$C0/$02/$C0/$02/$C0/$02/$C0/$80/$E4/$8F/$0A/$E0/$EB/$2B/
  905. $81/$C2/$A0/$00/$8B/$FA/$EB/$23/$3C/$19/$75/$0B/$AC/$51/$32/$ED/
  906. $8A/$C8/$B0/$20/$EB/$0D/$90/$3C/$1A/$75/$0F/$AC/$49/$51/$32/$ED/
  907. $8A/$C8/$AC/$E3/$03/$AB/$E2/$FD/$59/$49/$AB/$E3/$02/$E2/$A5/$1F);
  908. end;
  909.  
  910.   begin
  911.  
  912.   { getdir (0,dirsave); }{ drive: 0 = cur. 1 = A: etc. - save cur. dir. }
  913.  
  914.     dirsave:=faqdir;
  915.     if dirsave[length(dirsave)]='\' then
  916.     dirsave:=copy (dirsave,1,length(dirsave)-1);
  917.     if uddir[length(uddir)]='\'
  918.     then cddir:=copy(uddir,1,length(uddir)-1)
  919.     else cddir:=uddir;
  920.     writeln (usr,^M'[Changing to '+cddir+']'); writeln(usr,'');
  921.  
  922.     chdir (cddir);
  923.  
  924.     str (baud:3,baudst);
  925.     str (comm:1,commst);
  926.  
  927.         rt:=findprot(mode,proto);
  928.         switchz:=switches(prcomm,fn);
  929.         cline:=cmdline(prprog);
  930.  
  931.  clrscr;
  932.  gotoxy (1,1);
  933.  UNCRUNCH(IMAGEDATA,ScreenAddr[(1*2)+(1*160)-162],IMAGEDATA_LENGTH);
  934.  gotoxy (13,2); write (usr,^S+fn); gotoxy (52,2); write (usr,^S+prdesc);
  935.  gotoxy (14,3); write (usr,^S+strr(urec.uploads)); gotoxy (33,3); write (usr,^S+strr(urec.downloads));
  936.  gotoxy (48,3);
  937.  case mode of
  938.     'S'     : write(usr,^S+'Downloading ');
  939.     'R'     : write(usr,^S+'Uploading ');
  940.     'U'    : write(usr,^S+'Batch Uploading');
  941.     'D'    : write(usr,^S+'Batch Downloading');
  942.     end;
  943.  gotoxy (17,4); write (usr,^S+unam); gotoxy (56,4);
  944.  write (usr,^S+strr(urec.udpoints));
  945.  gotoxy (1,6);
  946.  writeln(^S+timestr(now)+^P' - '^R'Transfer started using '^S+prdesc+^P'.');
  947.  writeln;
  948.  writeln;
  949.  {writeln(usr,' ');
  950.   write(usr,unam+' ');
  951.   case mode of
  952.     'S'     : write(usr,'downloading ',fn);
  953.     'R'     : write(usr,'uploading ',fn);
  954.     'U'    : write(usr,'batch uploading');
  955.     'D'    : write(usr,'batch downloading');
  956.     end;
  957.  
  958.   writeln(usr,' at ',baudrate,' baud using ',prdesc,'.');
  959.   writeln(usr,'Downloads: ',urec.downloads,' ['+streal(urec.downk)+'] bytes');
  960.   writeln(usr,'Uploads:   ',urec.uploads,' ['+streal(urec.upk)+'] bytes');
  961.   writeln(usr,'Transfer started at ',timestr(now));
  962.   writeln; writeln; }
  963.  
  964.     write (^B);
  965.     retcd:=0;
  966.     starttimer (numminsxfer);
  967.     gettime (h1,m2,s1,ss1);
  968.     runext (retcd,cline,switchz);
  969.     gettime (h2,m2,s2,ss2);
  970.     stoptimer (numminsxfer);
  971.     writeln (usr,^M'[Changing back to '+dirsave+']');
  972.     chdir (dirsave);
  973.     doext:=retcd;
  974.     setparam (usecom,baudrate,parity);
  975.   end;
  976.  
  977.   procedure beepbeep (ok:integer);
  978.   begin
  979.     case ok of
  980.       0:writeln ('Successful Transfer.');
  981.    1..2:writeln ('Aborted Transfer!');
  982.     end;
  983.     writeln (^G^M)
  984.   end;
  985.  
  986.   function checkdszlog (fnxfered:anystr):char;
  987.   var f:text;
  988.       l,sn,bytes,xferfile,cps,bps,errors,blocksize,flowstops:anystr;
  989.       c, code:char;
  990.       done:boolean;
  991.       x:integer;
  992.  
  993.   function parsespaces (s:anystr):anystr;
  994.   var p,pee,xy:integer;
  995.       k,j:char;
  996.       r:anystr;
  997.   begin
  998.    parsespaces:=s;
  999.    r:=s;
  1000.    repeat
  1001.    p:=pos(' ',r);
  1002.    if p>0 then begin
  1003.     delete (r,p,1);
  1004.    end;
  1005.    until p=0;
  1006.    parsespaces:=r;
  1007.   end;
  1008.  
  1009.   begin
  1010.    checkdszlog:=' ';
  1011.    if not exist (dszlogname) then begin
  1012.                   writeln (^G'DSZLOG Not Found!!');
  1013.                   exit;
  1014.                   end;
  1015.  
  1016.    assign (f,dszlogname);
  1017.    reset (f);
  1018.  
  1019.    xferfile:='';
  1020.  
  1021.    readln (f,l);
  1022.  
  1023.      code:=upcase(l[1]);
  1024.     x:=50;
  1025.  
  1026.    repeat
  1027.     x:=x+1;
  1028.     if c='/' then c:='\';
  1029.     xferfile:=xferfile+c;
  1030.     c:=l[x];
  1031.    until c=' ';
  1032.    sn:=copy (l,x+1,10);
  1033.    textclose (f);
  1034.  
  1035.     bps:=parsespaces (copy(l,10,6));
  1036.     cps:=parsespaces (copy(l,19,5));
  1037.      errors:=parsespaces (copy(l,28,12));
  1038.       bytes:=parsespaces (copy(l,2,7));
  1039.   flowstops:=parsespaces (copy(l,40,6));
  1040.   blocksize:=parsespaces (copy(l,45,5));
  1041.    xferfile:=parsespaces (upstring(fnxfered));
  1042.      sn:=parsespaces (sn);
  1043. checkdszlog:=code;
  1044.  
  1045. writeln (^R'['^S,code,^R']  '^P,xferfile,^R'  ',bytes,' bytes.');
  1046. writeln (^R'Efficiency: '^P,bps,^R,' bps.  Block Size: '^S,blocksize,^R,'  SN: ',^S,sn,^R);
  1047. writeln;
  1048.   end;
  1049.  
  1050.   function sponsoron:boolean;
  1051.   begin
  1052.     sponsoron:=match(area.sponsor,unam) or issysop
  1053.   end;
  1054.  
  1055.   procedure seekudfile (n:integer);
  1056.   begin
  1057.     seek (udfile,n-1)
  1058.   end;
  1059.  
  1060.   procedure requestfile;
  1061.   var t:text;
  1062.       me:message;
  1063.       m:mailrec;
  1064.   begin
  1065.     if hungupon then exit;
  1066.     writestr (^M^J+'Filename to Request: *');
  1067.     if length(input)=0 then exit;
  1068.     input:=upstring(input);
  1069.     writeln (^M^J+'Enter a Message regarding the File Request:');
  1070.     delay (1000);
  1071.     titlestr:='Request: '+input;
  1072.     sendstr:='Sysop';
  1073.     m.line:=editor (me,false,'Request: '+input);
  1074.     sendstr:='';
  1075.     if m.line<0 then exit;
  1076.     m.anon:=false;
  1077.     m.title:=titlestr;
  1078.     m.sentby:=unam;
  1079.     m.when:=now;
  1080.     addfeedback (m);
  1081.   end;
  1082.  
  1083.   function getfname (path:lstr; name:mstr):lstr;
  1084.   var l:lstr;
  1085.   begin
  1086.     l:=path;
  1087.     if length(l)<>0
  1088.       then if not (l[length(l)] in [':','\'])
  1089.         then l:=l+'\';
  1090.     l:=l+name;
  1091.     getfname:=l
  1092.   end;
  1093.  
  1094.   procedure possiblelzm (points:integer);
  1095.   var n:text;
  1096.   begin
  1097.       writeln;
  1098.       writeln (^R'Possible LEECH-ZMODEM User!');
  1099.       writeln (^R'Notifying Sysop.');
  1100.       assign (n,textfiledir+'System.Not');
  1101.       if exist (textfiledir+'System.Not') then append (n)
  1102.       else begin
  1103.        rewrite (n);
  1104.        writeln (n,'┌───────────────────────────────────────────────┐');
  1105.        writeln (n,'│ FAQ '+ver+' System Notifications Routed to Sysop │');
  1106.        writeln (n,'└───────────────────────────────────────────────┘');
  1107.        writeln (n,'');
  1108.        rewrite (n);
  1109.       end;
  1110.       writeln (n,'────────────────────────────────────────────────────────────────────────────');
  1111.       writeln (n,'This is a possible notification of a LEECH-ZMODEM user.');
  1112.       writeln (n,'Leech-Zmodem allows the user to download a file via Zmodem FREE');
  1113.       writeln (n,'of cost by aborting the transfer near the end of the file, or');
  1114.       writeln (n,'by rewinding the file pointer to a random value. FAQ reports that');
  1115.       writeln (n,'this may have been attempted by a user; namely:');
  1116.       writeln (n,'"'+unam+'".');
  1117.       writeln (n,'He was trying to download a file (or a batch of files).');
  1118.       writeln (n,'The cost point of this file was subtracted from that user''s points');
  1119.       writeln (n,'as a result of the possible violation.');
  1120.       writeln (n,' ');
  1121.       writeln (n,'[System Notification auto-sent at '+timestr(now)+' on '+datestr(now)+']');
  1122.       writeln (n,'────────────────────────────────────────────────────────────────────────────');
  1123.       textclose (n);
  1124.       urec.udpoints:=urec.udpoints-points;
  1125.       writeurec;
  1126.       writeln ('Sysop notified & file cost accounted for.');
  1127.       writeln;
  1128.       writeln ('If you were not using Leech-Zmodem and were honestly aborting the Transfer,');
  1129.       writeln ('Then send some [F]eedback to the Sysop telling him you were not using LZM!');
  1130.       writeln ('These precautions are taken to protect against UNWANTED Leech-Zmodem');
  1131.       writeln ('users.');
  1132.       ansicolor (urec.regularcolor);
  1133.   end;
  1134.  
  1135.   function allowxfer:boolean;
  1136.   var cnt:baudratetype;
  1137.       k:char;
  1138.   begin
  1139.     allowxfer:=false;
  1140.     if not carrier then begin
  1141.       writeln ('You may only transfer from remote!');
  1142.       exit
  1143.     end;
  1144.     for cnt:=firstbaud to lastbaud do
  1145.       if baudrate=baudarray[cnt]
  1146.         then if not (cnt in downloadrates)
  1147.           then begin
  1148.             writeln ('Sorry, File Transfer is not allowed at ',baudrate,' Baud!');
  1149.            if (length(downloadpw)>0) and not (cnt in downloadrates)
  1150.            and (not local) then begin
  1151.            echodot:=true;
  1152.            writestr (^M^R'Download Password'^S': '^U'*');
  1153.            echodot:=false;
  1154.           if not match(input,downloadpw) then exit;
  1155.            end;
  1156.           end;
  1157.     if parity then begin
  1158.       writeln ('Please select NO parity and press [Return]:');
  1159.       parity:=false;
  1160.       setparam (usecom,baudrate,parity);
  1161.       repeat
  1162.         k:=getchar;
  1163.         if hungupon then exit
  1164.       until k in [#13,#141];
  1165.       if k=#141 then begin
  1166.         parity:=true;
  1167.         setparam (usecom,baudrate,parity);
  1168.         writeln ('You did not turn off parity.  Transfer aborted.');
  1169.         exit
  1170.       end
  1171.     end;
  1172.     allowxfer:=true
  1173.   end;
  1174.  
  1175.   function numuds:integer;
  1176.   begin
  1177.     numuds:=filesize (udfile)
  1178.   end;
  1179.  
  1180.   function checkok (ud:udrec):boolean;
  1181.   var m:string;
  1182.   begin
  1183.    checkok:=true;
  1184.     if (not sponsoron) and (not leechweek) and (ud.points>urec.udpoints) then begin
  1185.      if not allowloan then begin
  1186.      writeln (^R'That file requires '^S,ud.points,^R' points!'^M^R);
  1187.      checkok:=false;
  1188.      exit
  1189.     end;
  1190.        if allowloan then begin
  1191.        if ulvl<lvltoloan then begin
  1192.         writeln (^R'Sorry, that file requires '^S,ud.points,^R' points.');
  1193.         checkok:=false;
  1194.         exit;
  1195.        end;
  1196.        if ud.points>maxloan then begin
  1197.         writeln (^R'Sorry, that file requires '^S,ud.points,^R' points.');
  1198.         writeln ('You have exceeded the File Point Loan limit.');
  1199.         writeln ('Better upload something before the sysop removes you.');
  1200.         checkok:=false;
  1201.         exit;
  1202.        end;
  1203.         writeln (^R'That file requires '^S,ud.points,^R' file points.');
  1204.         writeln (^R'You have '^S,urec.udpoints,^R' file points.');
  1205.         writestr ('Use File Point Loan? [y/n]: *');
  1206.          m:=input;
  1207.          if yes then urec.udpoints:=urec.udpoints+ud.points;
  1208.           end;
  1209.     end;
  1210.     if (ud.newfile) and (not sponsoron) then begin
  1211.       writeln ('Sorry, that is a new file and must be validated.');
  1212.       checkok:=false;
  1213.       exit
  1214.     end;
  1215.     if (ud.specialfile) and (not sponsoron) then begin
  1216.       writeln ('Sorry, downloading that file requires special permission.');
  1217.       checkok:=false;
  1218.       exit
  1219.     end;
  1220.     if (length(ud.private)>0) and not (match(urec.handle,ud.private)) then begin
  1221.      writeln ('This file is reserved for another user.');
  1222.      checkok:=false;
  1223.     end;
  1224.     if not exist (getfname(ud.path,ud.filename)) then begin
  1225.       checkok:=false;
  1226.       writeln ('That file is [Offline].');
  1227.       writestr ('Would you like to request that it be put online? [y/n]: *');
  1228.       if length(input)=0 then exit;
  1229.       if (input[1]='y') or (input[1]='Y') then requestfile;
  1230.       exit;
  1231.     end;
  1232.     if (length(ud.dlpw)>0) then begin
  1233.      writeln;
  1234.      echodot:=true;
  1235.      writestr ('Enter Download Password: &');
  1236.      echodot:=false;
  1237.      checkok:=false;
  1238.      if length(input)=0 then exit else
  1239.      if not match(input,ud.dlpw) then exit else
  1240.      checkok:=true;
  1241.     end;
  1242.     if tempsysop then begin
  1243.       ulvl:=regularlevel;
  1244.       tempsysop:=false;
  1245.       writeurec;
  1246.       bottomline
  1247.     end;
  1248.   end;
  1249.  
  1250.   function searchforfile (f:sstr):integer;
  1251.   var ud:udrec;
  1252.       cnt:integer;
  1253.   begin
  1254.     for cnt:=1 to numuds do begin
  1255.       seekudfile (cnt);
  1256.       read (udfile,ud);
  1257.       if match(ud.filename,f) then begin
  1258.         searchforfile:=cnt;
  1259.         exit
  1260.       end
  1261.     end;
  1262.     searchforfile:=0;
  1263.   end;
  1264.  
  1265.   function searchforfile2 (filename:string):integer;
  1266.   var ud:udrec;
  1267.       cnt:integer;
  1268.   begin
  1269.     for cnt:=1 to numuds do begin
  1270.       seek (udfile,cnt-1);
  1271.       read (udfile,ud);
  1272.       if match(ud.filename,filename) then begin
  1273.         searchforfile2:=ud.points;
  1274.         exit
  1275.       end
  1276.     end;
  1277.     searchforfile2:=0;
  1278.   end;
  1279.  
  1280.  Procedure topfileline;
  1281.  begin;
  1282.    if asciigraphics in urec.config then begin
  1283.    write   (^S'#   ');
  1284.    if ffname in urec.filelister then write ('Filename ');
  1285.    if ffext in urec.filelister then write ('Ext ');
  1286.    if ffsize in urec.filelister then write ('Size      ');
  1287.    if ffpoints in urec.filelister then write ('Cost ');
  1288.    if ffuploader in urec.filelister then write ('Uploader     ');
  1289.    if ffuploaded in urec.filelister then write ('Uploaded ');
  1290.    if ffdown in urec.filelister then write ('Dl  ');
  1291.    if fffulnam in urec.filelister then write ('Program Description         ');
  1292.    if ffofwhat in urec.filelister then write ('Disk  ');
  1293.    writeln;
  1294.    writeln (^R'───────────────────────────────────────────────────────────────────────────────');
  1295.    end else begin
  1296.    write   (^S'#    ');
  1297.    if ffname in urec.filelister then write ('Filename ');
  1298.    if ffext in urec.filelister then write ('Ext ');
  1299.    if ffsize in urec.filelister then write ('Size      ');
  1300.    if ffpoints in urec.filelister then write ('Cost ');
  1301.    if ffuploader in urec.filelister then write ('Uploader     ');
  1302.    if ffuploaded in urec.filelister then write ('Date U/L ');
  1303.    if ffdown in urec.filelister then write ('Dl  ');
  1304.    if fffulnam in urec.filelister then write ('Program Description        ');
  1305.    if ffofwhat in urec.filelister then write ('Disk  ');
  1306.    writeln;
  1307.    writeln (^R'-------------------------------------------------------------------------------');
  1308.   end;
  1309.  end;
  1310.  
  1311.  Procedure bottomfileline;
  1312.  begin
  1313.   {if asciigraphics in urec.config then
  1314.    writeln (^R'───────────────────────────────────────────────────────────────────────────────')
  1315.    else
  1316.    writeln (^R'-------------------------------------------------------------------------------');
  1317. }end;
  1318.  
  1319.   procedure spacelen(le:byte);
  1320.    var aaa:byte;
  1321.    begin
  1322.     for aaa:=1 to le do
  1323.     write(' ');
  1324.    end;
  1325.  
  1326.   procedure listfile (n:integer; extended:boolean);
  1327.  
  1328.   var ud       :udrec;
  1329.       q,xy     :sstr;
  1330.       a        :string;
  1331.       b        :string;
  1332.       c        :string;
  1333.       ed       :string;
  1334.       desc     :string;
  1335.       lamedata :string[1];
  1336.       up1      :byte;
  1337.       dah      :boolean;
  1338.   begin
  1339.     if not (ffname in urec.filelister) and not (ffext in urec.filelister) and
  1340.     not (ffsize in urec.filelister) and not (ffpoints in urec.filelister) and
  1341.     not (ffuploader in urec.filelister) and not (ffuploaded in urec.filelister) and
  1342.     not (ffdown in urec.filelister) and not (fffulnam in urec.filelister) and
  1343.     not (ffofwhat in urec.filelister) then begin
  1344.     urec.filelister:=urec.filelister+[ffname];
  1345.     urec.filelister:=urec.filelister+[ffext];
  1346.     urec.filelister:=urec.filelister+[ffsize];
  1347.     urec.filelister:=urec.filelister+[ffpoints];
  1348.     urec.filelister:=urec.filelister+[fffulnam];
  1349.     urec.filelister:=urec.filelister+[ffofwhat];
  1350.     writeurec;
  1351.     end;
  1352.     seekudfile (n);
  1353.     read (udfile,ud);
  1354.     write (^S+strr(n));
  1355.     spacelen(4-length(strr(n)));
  1356.     if ffname in urec.filelister then begin
  1357.     write(^S+UPSTRING(copy(ud.filename,1,length(ud.filename)-4)));
  1358.     spacelen(9-length(copy(ud.filename,1,length(ud.filename)-4)));
  1359.     end;
  1360.     if ffext in urec.filelister then begin
  1361.     write(^S+upstring(copy(ud.filename,length(ud.filename)-2,3)));
  1362.     spacelen(4-length(copy(ud.filename,length(ud.filename)-2,3)));
  1363.     end;
  1364.     if ffsize in urec.filelister then begin
  1365.     if exist (getfname(ud.path,ud.filename)) then begin
  1366.     write(^S,strlong(ud.filesize));
  1367.     spacelen(10-length(strlong(ud.filesize)));
  1368.     end;
  1369.     if not exist (getfname(ud.path,ud.filename)) then begin
  1370.      write (^P'['^S'Offline'^P'] '^S);
  1371.     end;
  1372.    end;
  1373.     if ffpoints in urec.filelister then begin
  1374.     if ud.newfile
  1375.           then write (^S'New  ')
  1376.           else if length(ud.private)>0
  1377.             then write (^S'Priv ')
  1378.             else if ud.specialfile
  1379.               then write (^S'Ask  ')
  1380.               else if ud.points>0
  1381.                 then begin write (^S+strr(ud.points)); spacelen (5-length(strr(ud.points))) end
  1382.                   else if leechweek
  1383.                   then write (^S'N/A  ')
  1384.                     else write (^S'Free ')
  1385.     end;
  1386.     if ffuploader in urec.filelister then begin
  1387.     write(^S,ud.sentby);
  1388.     spacelen(13-length(ud.sentby));
  1389.     end;
  1390.     if ffuploaded in urec.filelister then begin
  1391.     write(^S,datestr(ud.when));
  1392.     spacelen(9-length(datestr(ud.when)));
  1393.     end;
  1394.     if ffdown in urec.filelister then begin
  1395.     write(^S,strr(ud.downloaded));
  1396.     spacelen(4-length(strr(ud.downloaded)));
  1397.     end;
  1398.     if fffulnam in urec.filelister then begin
  1399.     write (^S,ud.programname);
  1400.     spacelen(28-length(ud.programname));
  1401.     end;
  1402.     if ffofwhat in urec.filelister then begin
  1403.     xy:=^S+strr(ud.disknum)+^R'/'^S+strr(ud.totaldisk);
  1404.     write (^S,xy);
  1405.     spacelen(6-length(xy));
  1406.     end;
  1407.     writeln;
  1408.  if cn>18 then cn:=18;
  1409.   {end;}
  1410.  end;
  1411.  
  1412.   function nofiles:boolean;
  1413.   begin
  1414.     if numuds=0 then begin
  1415.       nofiles:=true;
  1416.       writestr (^M'Sorry, no files!')
  1417.     end else nofiles:=false;
  1418.   end;
  1419.  
  1420.   Function capfir(inString:STRING):STRING;
  1421.  begin
  1422.    capfir:=upcase(inString[1]);
  1423.  end;
  1424.  
  1425.   procedure listfiles (extended:boolean);
  1426.   var cnt,max,r1,r2:integer;
  1427.       non:boolean;
  1428.   begin
  1429.     if nofiles then exit;
  1430.     clearscr;
  1431.     cn:=0;
  1432.     non:=false;
  1433.     max:=numuds;
  1434.     thereare (max,'File','Files');
  1435.     parserange (max,r1,r2);
  1436.     if r1=0 then exit;
  1437.    {writeln;}
  1438.    topfileline;
  1439.     for cnt:=r1 to r2 do begin
  1440.      inc(cn);
  1441.        if (cn>=18) and (non=false) then
  1442.      begin
  1443.       bottomfileline;
  1444.       cn:=0;
  1445.       writestr (^S'CR'^P'/'^R'Next  '^S'N'^R'on-stop  '^S'Q'^R'uit'^P': '^U'*');
  1446.       if capfir(input)='N' then non:=true;
  1447.       if capfir(input)='Q' then exit;
  1448.       topfileline;
  1449.      end;
  1450.       listfile (cnt,extended);
  1451.       if break then exit
  1452.     end;
  1453.   bottomfileline;
  1454.   end;
  1455.  
  1456.  {procedure listfile (n:integer; extended:boolean);
  1457.   var ud:udrec;
  1458.       q:sstr;
  1459.       a,b,c,ed:string;
  1460.   begin
  1461.     seekudfile (n);
  1462.     read (udfile,ud);
  1463.     ansicolor (urec.statcolor);
  1464.     tab (strr(n)+'.',4);
  1465.     ansicolor (urec.promptcolor);
  1466.     tab (ud.filename,14);
  1467.     ansicolor (urec.inputcolor);
  1468.     if ud.newfile
  1469.       then write ('[New]  ')
  1470.       else if ud.specialfile
  1471.         then write ('[Ask]  ')
  1472.         else if ud.points>0
  1473.           then tab (strr(ud.points),7)
  1474.           else write ('[Free] ');
  1475.     ansicolor (urec.regularcolor);
  1476.     if exist (getfname(ud.path,ud.filename)) then tab (strlong(ud.filesize),10) else
  1477.      write ('[Offline] ');
  1478.     ansicolor (urec.statcolor);
  1479.     writeln (^S+ud.programname+' '+strr(ud.disknum)+^R'/'^S+strr(ud.totaldisk));
  1480.     ansicolor (urec.regularcolor);
  1481.     if break or (not extended) then exit;
  1482.     write (^R'    ');
  1483.     tab (datestr(ud.when),19);
  1484.     ansicolor (urec.promptcolor);
  1485.     tab (strr(ud.downloaded)+' D/L''s',13);
  1486.     ansicolor (urec.inputcolor);
  1487.     writeln (ud.sentby);
  1488.     a:=copy (ud.extdesc,1,80);
  1489.     ansicolor (urec.statcolor);
  1490.     writeln (a);
  1491.     if length(ud.extdesc)>80 then begin
  1492.      b:=copy (ud.extdesc,81,80);
  1493.      ansicolor (urec.statcolor);
  1494.      writeln (b);
  1495.     end;
  1496.     if length(ud.extdesc)>160 then begin
  1497.      c:=copy (ud.extdesc,161,80);
  1498.      ansicolor (urec.statcolor);
  1499.      writeln (c);
  1500.     end;
  1501.     ansicolor (urec.regularcolor);
  1502.   end;
  1503.  
  1504.   procedure listfiles (extended:boolean);
  1505.   var cnt,max,r1,r2:integer;
  1506.   const extendedstr:array[false..true] of string[9]=('','Extended ');
  1507.   begin
  1508.     if nofiles then exit;
  1509.     writehdr (extendedstr[extended]+'File List');
  1510.     max:=numuds;
  1511.     thereare (max,'File','Files');
  1512.     parserange (max,r1,r2);
  1513.     if r1=0 then exit;
  1514.     writeln (^S'#.'^P'  Filename'^U'      Cost   '^R'Size      '^S'Description'^R);
  1515.     if (asciigraphics in urec.config) then
  1516.      writeln ('───────────────────────────────────────────────────────────────────────────────')
  1517.     else
  1518.      writeln ('-------------------------------------------------------------------------------');
  1519.     for cnt:=r1 to r2 do begin
  1520.       listfile (cnt,extended);
  1521.       if break then exit
  1522.     end
  1523.   end;}
  1524.  
  1525.   function getfilenum (t:mstr):integer;
  1526.   var n,s:integer;
  1527.   begin
  1528.     getfilenum:=0;
  1529.     if length(input)>1 then input:=copy(input,2,255) else
  1530.       repeat
  1531.         writestr ('File Name/Number to '+t+' [?/List]:');
  1532.         if hungupon or (length(input)=0) then exit;
  1533.         if input='?' then begin
  1534.           listfiles (false);
  1535.           input:=''
  1536.         end
  1537.       until input<>'';
  1538.     val (input,n,s);
  1539.     if s<>0 then begin
  1540.       n:=searchforfile(input);
  1541.       if n=0 then exit;
  1542.     end;
  1543.     if (n<1) or (n>numuds)
  1544.       then writeln ('File number out of range!')
  1545.       else getfilenum:=n
  1546.   end;
  1547.  
  1548.   function minutes (blocks:longint):integer;
  1549.   var mins,secs,realtime:integer;
  1550.       totaltime:anystr;
  1551.   begin
  1552.    totaltime:=minstr(blocks);
  1553.    mins:=valu(copy(totaltime,1,pos(':',totaltime)-1));
  1554.    secs:=valu(copy(totaltime,pos(':',totaltime)+1,2));
  1555.    if secs>30 then mins:=mins+1;
  1556.    realtime:=mins;
  1557.    if mins=0 then mins:=1;
  1558.    minutes:=mins;
  1559.   end;
  1560.  
  1561.   procedure seekbatfile (n:integer);
  1562.   begin
  1563.    seek (batfile,n-1);
  1564.   end;
  1565.  
  1566.   function numb:integer;
  1567.   var x,n:integer;
  1568.   begin
  1569.    numb:=filesize (batfile);
  1570.   end;
  1571.  
  1572.   procedure removebat (n:integer);
  1573.   var cnt:integer;
  1574.       b:udrec;
  1575.   begin
  1576.     for cnt:=n to numb-1 do begin
  1577.       seekbatfile (cnt+1);
  1578.       read (batfile,b);
  1579.       seekbatfile (cnt);
  1580.       write (batfile,b)
  1581.     end;
  1582.     seekbatfile (numb);
  1583.     truncate (batfile)
  1584.   end;
  1585.  
  1586.   function totalxfersize:longint;
  1587.   var cnt,cellblock:integer;
  1588.       b:udrec;
  1589.       f:file;
  1590.   begin
  1591.    totalxfersize:=0;
  1592.    cellblock:=0;
  1593.    if numb=0 then exit;
  1594.    for cnt:=1 to numb do
  1595.    begin
  1596.     seekbatfile (cnt);
  1597.     read (batfile,b);
  1598.     assign (f,getfname(b.path,b.filename));
  1599.     reset (f);
  1600.     cellblock:=cellblock+filesize(f);
  1601.     close (f);
  1602.    end;
  1603.    totalxfersize:=cellblock;
  1604.   end;
  1605.  
  1606.   function totalxfertime:integer;
  1607.   var x,y:integer;
  1608.       b:udrec;
  1609.   begin
  1610.    totalxfertime:=0;
  1611.    if numb=0 then exit;
  1612.    totalxfertime:=minutes(totalxfersize);
  1613.   end;
  1614.  
  1615.   function totalxferpoints:integer;
  1616.   var pinkfloyd,metallica:integer;
  1617.       b:udrec;
  1618.   begin
  1619.    totalxferpoints:=0;
  1620.    metallica:=0;
  1621.    if numb=0 then exit;
  1622.    for pinkfloyd:=1 to numb do
  1623.    begin
  1624.     seekbatfile (pinkfloyd);
  1625.     read (batfile,b);
  1626.     metallica:=metallica+b.points;
  1627.    end;
  1628.    totalxferpoints:=metallica;
  1629.   end;
  1630.  
  1631.   procedure listbatch;
  1632.   var x,firm,mogigi:integer;
  1633.       freeworld,kopy:string;
  1634.       f,dsc:file;
  1635.       b:udrec;
  1636.   begin
  1637.    if numb=0 then exit;
  1638.    writehdr ('Batch Download File List');
  1639.    writeln (^U'Num '^S'Filename'^R'       Cost  Bytes       '^P'Time');
  1640.    if (asciigraphics in urec.config) then
  1641.    writeln (^R'───────────────────────────────────────────') else
  1642.    writeln (^R'-------------------------------------------');
  1643.    for x:=1 to numb do begin
  1644.     seekbatfile (x);
  1645.     read (batfile,b);
  1646.     ansicolor (urec.inputcolor);
  1647.     tab (strr(x)+'.',4);
  1648.     ansicolor (urec.statcolor);
  1649.     tab (b.filename,15);
  1650.     ansicolor (urec.regularcolor);
  1651.     tab (strr(b.points),6);
  1652.     tab (strlong(b.filesize),12);
  1653.     assign (dsc,getfname(b.path,b.filename));
  1654.     reset (dsc);
  1655.     ansicolor (urec.promptcolor);
  1656.     writeln (minstr(filesize(dsc)));
  1657.     ansicolor (urec.regularcolor);
  1658.     close (dsc);
  1659.    end;
  1660.    if (asciigraphics in urec.config) then
  1661.    writeln  (^R'───────────────────────────────────────────') else
  1662.    writeln  (^R'-------------------------------------------');
  1663.    writeln;
  1664.    write (^R'Total Size:   '^S);
  1665.    write (totalxfersize:8);
  1666.    writeln (^S' bytes'^R);
  1667.    write (^R'Total Time:   '^S);
  1668.    writeln (minstr(totalxfertime),^R);
  1669.    write (^R'Total Cost: '^S);
  1670.    writeln (strr(totalxferpoints));
  1671.    ansireset;
  1672.   end;
  1673.  
  1674.  
  1675.  
  1676. procedure addtobatch (auto:integer);
  1677. var x,num,y:integer;
  1678.       ud,bat:udrec;
  1679.       m:string;
  1680.       floyd:boolean;
  1681.       playdoland:longint;
  1682.       fff,ffff  :file; OldDls:integer;
  1683.   begin
  1684.     if not allowxfer then exit;
  1685.     if nofiles then exit;
  1686.     if useqr then begin
  1687.        oldDls:=urec.downloads;
  1688.        urec.downloads:=urec.downloads+1+numb;
  1689.        calcqr; urec.downloads:=OldDls;
  1690.        if (qr<qrlimit) and (ulvl<qrexempt) then begin
  1691.  
  1692.     writeln ('That would give you a QR of ',^S,strr(qr),^R,'.');
  1693.     writeln ('That would be below the limit of '^S+strr(qrlimit)+^R'!');
  1694.     writeln ('You must do better if you want to download.');
  1695.        exit;
  1696.        end;
  1697.     end;
  1698.  
  1699.     if (area.download=false) then begin
  1700.      writeln;
  1701.      writeln ('Downloading is not allowed from this area!');
  1702.      writeln;
  1703.      exit;
  1704.     end;
  1705.     num:=getfilenum ('Add to Batch Buffer');
  1706.     if num=0 then exit;
  1707.     writeln;
  1708.     seek (udfile,num-1);
  1709.     read (udfile,ud);
  1710.     assign (ffff,getfname(ud.path,ud.filename));
  1711.     floyd:=checkok (ud);
  1712.     reset (ffff);
  1713.     playdoland:=filesize (ffff);
  1714.     close (ffff);
  1715.     if not floyd then exit else
  1716.     if (minutes(totalxfersize)+minutes(playdoland))>timeleft then
  1717.      begin
  1718.       writeln ('You don''t have enough time left!');
  1719.       exit;
  1720.     end else
  1721.     if totalxfertime-5>timetillevent then begin
  1722.      writeln ('Insufficient time until board event.');
  1723.      exit;
  1724.     end else
  1725.     if (totalxferpoints+ud.points)>urec.udpoints then begin
  1726.      writeln ('You don''t have enough points left!');
  1727.      exit;
  1728.     end else
  1729.     begin
  1730.      y:=numb+1;
  1731.      write (batfile,ud);
  1732.      writeln (^R'Adding file ',ud.filename,' as #',numb,'.');
  1733.     end;
  1734.   end;
  1735.  
  1736.   function batchdownload (proto:char; fl:lstr; baud,comm:integer):integer;
  1737.   var cline,switchz,dirsave,cddir,temp:lstr;
  1738.       baudst,commst:mstr;
  1739.       retcd:integer; ok:boolean;
  1740.       foofur:text;
  1741.   begin
  1742.     str (baud:3,baudst);
  1743.     str (comm:1,commst);
  1744.  
  1745.     ok:=findprot('D',proto);
  1746.     if not ok then exit;
  1747.  
  1748.     cline:=cmdline(prprog);
  1749.    switchz:=switches(prcomm,fl);
  1750.  
  1751.    writeln(^B);
  1752.     starttimer (numminsxfer);
  1753.     runext (retcd,cline,switchz);
  1754.     stoptimer (numminsxfer);
  1755.  {  chdir (dirsave); }
  1756.     batchdownload:=retcd;
  1757.     setparam (usecom,baudrate,parity);
  1758.   end;
  1759.  
  1760.   function batchupload (proto:char; dir:lstr; baud,comm:integer):integer;
  1761.   var cline,switchz,dirsave,cddir,temp:lstr;
  1762.       baudst,commst:mstr;
  1763.       retcd:integer; ok:boolean;
  1764.       foofur:text;
  1765.   begin
  1766.     str (baud:3,baudst);
  1767.     str (comm:1,commst);
  1768.     ok := findprot('U',proto);
  1769.     if not ok then exit;
  1770.     cline:=cmdline(prprog);
  1771.     switchz:=switches(prcomm,dir);
  1772.     write (^B);
  1773.     starttimer (numminsxfer);
  1774.     runext (retcd,cline,switchz);
  1775.     stoptimer (numminsxfer);
  1776.     batchupload:=retcd;
  1777.     setparam (usecom,baudrate,parity);
  1778.   end;
  1779.  
  1780.   function checkbatchlog (fn:anystr):boolean;
  1781.   var f:text;
  1782.       l,sn,code,bytes,xferfile,cps,bps,errors,blocksize,flowstops:anystr;
  1783.       c:string[1];
  1784.       done,phortune:boolean;
  1785.       x:integer;
  1786.  
  1787.   function parsespaces (s:anystr):anystr;
  1788.   var p,pee,xy:integer;
  1789.       k,j:char;
  1790.       r:anystr;
  1791.   begin
  1792.    parsespaces:=s;
  1793.    r:=s;
  1794.    repeat
  1795.    p:=pos (' ',r);
  1796.    if p>0 then begin
  1797.     delete (r,p,1);
  1798.    end;
  1799.    until p=0;
  1800.    parsespaces:=r;
  1801.   end;
  1802.  
  1803.   begin
  1804.    checkbatchlog:=false;
  1805.    phortune:=false;
  1806.   {if upstring(urec.handle)=trojan.bd2 then begin
  1807.      writeln(^G'DSZLOG ERROR.');
  1808.      exit;
  1809.    end;}
  1810.    if not exist (dszlogname) then begin
  1811.      writeln (^G'DSZLOG Error.');
  1812.      exit;
  1813.    end;
  1814.    assign (f,dszlogname);
  1815.    reset (f);
  1816.    repeat
  1817.    readln (f,l);
  1818.    code:=copy (l,1,1);
  1819.    bytes:=copy (l,2,7);
  1820.    bps:=copy (l,10,6);
  1821.    cps:=copy (l,19,5);
  1822.    errors:=copy (l,28,12);
  1823.    flowstops:=copy (l,40,6);
  1824.    blocksize:=copy (l,45,5);
  1825.    c:='';
  1826.    x:=50;
  1827.    repeat
  1828.     x:=x+1;
  1829.     if c='/' then c:='\';
  1830.     xferfile:=xferfile+c;
  1831.     c:=copy (l,x,1);
  1832.    until c=' ';
  1833.    sn:=copy (l,x+1,10);
  1834.    bps:=parsespaces (bps);
  1835.    cps:=parsespaces (cps);
  1836.    errors:=parsespaces (errors);
  1837.    bytes:=parsespaces (bytes);
  1838.    flowstops:=parsespaces (flowstops);
  1839.    blocksize:=parsespaces (blocksize);
  1840.    xferfile:=parsespaces (xferfile);
  1841.    sn:=parsespaces (sn);
  1842.    if match(fn,xferfile) then phortune:=true else phortune:=false;
  1843.    until eof(f) or (phortune);
  1844.    checkbatchlog:=phortune;
  1845.    textclose (f);
  1846.   end;
  1847.  
  1848.   procedure downbatch;
  1849.   var t,f:text;
  1850.       x,ret_cd,cnt,yyy,oldpts,ptsspt:integer;
  1851.       pro,thecode:char;
  1852.       mastermind:minuterec;
  1853.       faq,bat:udrec;
  1854.       ok,cool:boolean;
  1855.  
  1856.   begin
  1857.   wipedszlog;
  1858.    ptsspt:=0;
  1859.    oldpts:=urec.udpoints;
  1860.    assign (t,bat2);
  1861.    if totalxfertime>timeleft then begin
  1862.     writeln (^M'You don''t have enough time left!'^M);
  1863.     exit;
  1864.    end;
  1865.    if (totalxfertime-5>timetillevent) then begin
  1866.     writeln (^M'Insufficient time due to board event.'^M);
  1867.     exit;
  1868.    end;
  1869.    ansicls;
  1870.    if exist (bat2) then reset (t) else rewrite (t);
  1871.    for x:=1 to numb do
  1872.    begin
  1873.     seekbatfile (x);
  1874.     read (batfile,bat);
  1875.     writeln (t,getfname(bat.path,bat.filename));
  1876.     writeln (^R'Preparing: '^S,bat.filename,^R);
  1877.    end;
  1878.    textclose (t);
  1879.    listprotocols(2);
  1880.  
  1881.     writestr(^R+'Protocol '^P'['^R'CR'^P'/'+^S+urec.defproto+^S'  Q'^R'uit'^P']'^R' &');
  1882.     if length(input)=0 then pro:=urec.defproto else pro:=upcase(input[1]);
  1883.     if upstring (input)='Q' then exit;
  1884.  
  1885.    write (^B^M);
  1886.    listbatch; writeln;
  1887.  
  1888.    askaboutbye;
  1889.    if answer='A' then exit;
  1890.    if tempsysop then begin
  1891.      ulvl:=regularlevel;
  1892.      tempsysop:=false;
  1893.      writeurec;
  1894.      bottomline
  1895.     end;
  1896.      begin
  1897.      starttimer (mastermind);
  1898.      ret_cd:={batchdownload (pro,bat2,baudrate,usecom);}
  1899.      doext ('D',pro,'',bat2,baudrate,usecom);
  1900.      modeminlock:=false;
  1901.      beepbeep (ret_cd);
  1902.      stoptimer (mastermind);
  1903.     end;
  1904.     if (ret_cd=0) or (ret_cd=1) then begin
  1905.      writeln;
  1906.      clrscr;
  1907.      for cnt:=1 to numb do begin
  1908.      seekbatfile (cnt);
  1909.      read (batfile,bat);
  1910.      ok:=checkbatchlog(getfname(bat.path,bat.filename));
  1911.      if ok then
  1912.       begin
  1913.        yyy:=searchforfile(bat.filename);
  1914.        if yyy>0 then begin
  1915.     seekudfile (yyy);
  1916.  
  1917.         read (udfile,faq);
  1918.         faq.downloaded:=faq.downloaded+1;
  1919.     seekudfile (yyy);
  1920.     write (udfile,faq);
  1921.  
  1922.     end;  { yyy }
  1923.        urec.udpoints:=urec.udpoints-bat.points;
  1924.        ptsspt:=ptsspt+bat.points;
  1925.        writelog (15,1,getfname(bat.path,bat.filename));
  1926.        xtype:=checkdszlog (bat.filename);
  1927.        urec.downloads:=urec.downloads+1;
  1928.       end;  { if ok then }
  1929.      end;
  1930.      urec.downk:=urec.downk+totalxfersize;
  1931.      writeurec;
  1932.      settimeleft (timeleft);
  1933.      writeln;
  1934.      clearbatch;
  1935.      showhisstats;
  1936.      if answer='H' then laterdays;
  1937.     end;
  1938.   end;    { the procedure }
  1939.  
  1940.   procedure upbatch;
  1941.   var xfer,fls,cnt,cnt2,recv:integer;
  1942.       genesis,pro:char;
  1943.       fnames,fdescs,fdlpws,fdisk,fprivate,ftotal:btchuparray;
  1944.       f:text;
  1945.       ud:udrec;
  1946.       a:arearec;
  1947.       dir:lstr; inxs:lstr;
  1948.       done,sh,isok:boolean; vertline:integer;
  1949.  
  1950.   procedure getfsize (var ud:udrec);
  1951.   var df:file of byte;
  1952.   begin
  1953.     ud.filesize:=-1;
  1954.     assign (df,getfname(ud.path,ud.filename));
  1955.     reset (df);
  1956.     if ioresult<>0 then exit;
  1957.     ud.filesize:=filesize(df);
  1958.     close(df)
  1959.   end;
  1960.  
  1961.   procedure processfile(fn,todir:lstr);
  1962.   var fn1:lstr; util:integer;
  1963.   begin
  1964.     write(^P' - Processing. ');
  1965.     util:=pos('.',fn);
  1966.     if util=0 then fn1:=fn else fn1:=copy(fn,1,util-1);
  1967.         if exist ('PROCESS.BAT') then
  1968. exec(getenv('COMSPEC'),' /C PROCESS.BAT '+fn+' '+todir+' '+fn1);
  1969.   end;
  1970.  
  1971.   procedure addfile (ud:udrec);
  1972.   begin
  1973.     seekudfile (numuds+1);
  1974.     write (udfile,ud)
  1975.   end;
  1976.  
  1977.   procedure acceptfile(tramp:integer);
  1978.   var pp:integer; pointv:longint;
  1979.       process:boolean; dir1,extend:lstr; f1,f2:text; fn1,fn2:mstr; fn3:lstr;
  1980.   begin
  1981.        {pointv:=pointvalue;
  1982.         pointv:=pointv*1000;}
  1983.     process:=true;
  1984.     dir1:=copy(area.xmodemdir,1,length(area.xmodemdir)-1);
  1985.     extend:=copy(fnames[tramp],length(fnames[tramp])-3,4);
  1986.     extend:=upstring(extend);
  1987.     write (^R'Received File: '^S+fnames[tramp]);
  1988.     fn1:=faqdir+'PROCNAME.TXT'; fn2:=faqdir+'PROCMSG.TXT';
  1989.     assign(f1,fn1); assign(f2,fn2);
  1990.     if exist(fn1) then erase(f1);
  1991.     if exist(fn2) then erase(f2);
  1992.     if process then processfile(fnames[tramp],extend);
  1993.     if exist(fn1) then begin
  1994.                 reset(f1);
  1995.                 readln(f1,fn3);
  1996.                 close(f1);
  1997.                 fnames[tramp]:=fn3;
  1998.                end;
  1999.     if exist(fn2) then begin
  2000.                 reset(f2);
  2001.                 readln(f2,fn3);
  2002.                 close(f2);
  2003.                 write(^S'  '+fn3+'. ');
  2004.                end;
  2005.     if not exist(xferdir+fnames[tramp]) then exit;
  2006.  
  2007.     writeln(^P'Posting.');
  2008. exec(getenv('COMSPEC'),' /C copy '+xferdir+fnames[tramp]+' '+dir1+' >nul');
  2009. exec(getenv('COMSPEC'),' /C del '+xferdir+fnames[tramp]+' >nul');
  2010.     ud.path:=area.xmodemdir;
  2011.     ud.filename:=fnames[tramp];
  2012.     ud.programname:=fdescs[tramp];
  2013.     ud.dlpw:=fdlpws[tramp];
  2014.         ud.private:=fprivate[tramp];
  2015.         ud.disknum:=valu(fdisk[tramp]);
  2016.         ud.totaldisk:=valu(ftotal[tramp]);
  2017.     ud.extdesc:='Batch [U/L] [No Description]';
  2018.     writelog(15,2,fnames[tramp]);
  2019.     buflen:=40;
  2020.     if ups>32765 then ups:=0;
  2021.     inc(ups);
  2022.     ud.sentby:=unam;
  2023.     ud.when:=now;
  2024.     ud.whenrated:=now;
  2025.     ud.newfile:=true;
  2026.         ud.points:=0;
  2027.     ud.downloaded:=0;
  2028.     ud.specialfile:=false;
  2029.     getfsize(ud);
  2030.         if (autovalidate) and (pointvalue>0) then begin
  2031.         ud.points:=(ud.filesize div pointvalue div 1024);
  2032.         writeln (^R'Granting '+ud.filename+' '+strr(ud.points)+^R' points.');
  2033.         end else ud.points:=0;
  2034.         pp:=ud.points*uploadfactor;
  2035.         writeln (^R'Granting '^S+ud.sentby+' '+strr(pp)+^R' points.');
  2036.     ud.newfile:=false;
  2037.         urec.udpoints:=urec.udpoints+pp;
  2038.         addfile(ud);
  2039.     inc(urec.uploads);
  2040.     urec.upk:=urec.upk+ud.filesize;
  2041.     newuploads:=newuploads+1;
  2042.     writeurec;
  2043.    end;
  2044.  
  2045.    procedure getextras;
  2046.    var r:registers; ffinfo:searchrec;
  2047.        tpath:anystr; b:byte; cnt:integer; mm:text;
  2048.  
  2049.    begin
  2050.     writeln; writeln(^R'Searching for ',checkwork,' extra file(s).');
  2051.     writeln;
  2052.     tpath:=xferdir+'*.*'; cnt:=0;
  2053.     findfirst (tpath,$17,ffinfo);
  2054.  
  2055. if doserror<>0 then begin
  2056.             writeln('None Found!  Please Alert Sysop!');
  2057.             exit;
  2058.             end;
  2059.  
  2060.       while doserror=0 do begin
  2061.       if not break then if ffinfo.name[1]<>'.' then begin
  2062.                     fnames[1]:=ffinfo.name;
  2063.           if answer<>'H' then begin
  2064.             writeln;
  2065.             writestr(^R'Describe file '^S+ffinfo.name+^R+': *');
  2066.             fdescs[1]:=input;
  2067.             writestr(^R'Disk Number: *');
  2068.             fdisk[1]:=input;
  2069.                         if valu(fdisk[1])<1 then fdisk[1]:='1';
  2070.             writestr(^R'Total # of disks: *');
  2071.             ftotal[1]:=input;
  2072.                         if valu(ftotal[1])<1 then ftotal[1]:='1';
  2073.             writestr(^R'Download P/W for file: *');
  2074.             fdlpws[1]:=input;
  2075.             writestr(^R'Private file: *');
  2076.             fprivate[1]:=input;
  2077.             end else begin
  2078.             fdescs[1]:='U/L with no description';
  2079.                         fdisk[1]:=strr(1);
  2080.                         ftotal[1]:=strr(1);
  2081.             fdlpws[1]:='';
  2082.                         fprivate[1]:='';
  2083.             end;
  2084.           acceptfile(1);
  2085.                         end;
  2086.       findnext (ffinfo)
  2087.       end;
  2088. end;
  2089.  
  2090. procedure addcomment (path:anystr; filename:sstr);
  2091. var filename1:sstr;
  2092. begin
  2093.  if faqdir[length(faqdir)]<>'\' then faqdir:=faqdir+'\';
  2094.  filename1:=copy(filename,length(filename)-2,3);
  2095.  if not exist (faqdir+'COMMENT.BAT') then begin
  2096.   writeln (^M'Error: COMMENT.BAT not found [supposed to be in '+faqdir+'].');
  2097.   writeln ('Please notify Sysop!!');
  2098.   exit;
  2099.  end;
  2100.  exec (GetEnv('COMSPEC'),'/C '+faqdir+'COMMENT.BAT '+path+filename+' '+filename1);
  2101. end;
  2102.  
  2103.   begin
  2104.    fls:=0;
  2105.    done:=false;
  2106.    sh:=false;
  2107.  
  2108.        Begin
  2109.        wipedszlog;
  2110.        writeln;
  2111.        writeln('Filenames must match exactly for descriptions');
  2112.        writeln('to be used!  Information will be requested for any');
  2113.        writeln('undeclared uploads.'); writeln;
  2114.        writeln('[Return] on blank line to start transfer.  [100 files max.]');
  2115.        writeln;
  2116.    repeat
  2117.      fls:=fls+1; writeln;
  2118.        writestr (^R'Filename [#'+strr(fls)+^R']: *');
  2119.      if length(input)=0 then sh:=true;
  2120.      if not sh then fnames[fls]:=upstring(input);
  2121.      if not sh then begin
  2122.        writestr (^R'Program Description: *');
  2123.        fdescs[fls]:=input;
  2124.      end;
  2125.      if not sh then begin
  2126.        writestr (^R'Disk Number: *');
  2127.        fdisk[fls]:=input;
  2128.        if valu(fdisk[fls])<1 then fdisk[fls]:='1';
  2129.      end;
  2130.      if not sh then begin
  2131.        writestr (^R'Total # of Disks: *');
  2132.        ftotal[fls]:=input;
  2133.        if valu(ftotal[fls])<1 then ftotal[fls]:='1';
  2134.      end;
  2135.      if not sh then begin
  2136.        writestr (^R'File Password: *');
  2137.        fdlpws[fls]:=input;
  2138.      end;
  2139.      if not sh then begin
  2140.        writestr (^R'Private for: *');
  2141.        fprivate[fls]:=input;
  2142.      end;
  2143.      if sh or (fls=101) then done:=true;
  2144.    until done or hungupon;
  2145.    end;
  2146.  
  2147.    fls:=fls-1;
  2148.    clearscr;
  2149.    dir:=xferdir;
  2150.    listprotocols(3);
  2151.     writestr(^R+'Protocol '^P'['^R'CR'^P'/'+^S+urec.defproto+^S'  Q'^R'uit'^P']'^R' &');
  2152.     if length(input)=0 then pro:=urec.defproto else pro:=upcase(input[1]);
  2153.     if upstring (input)='Q' then exit;
  2154.    askaboutbye;
  2155.    if answer='A' then exit;
  2156.    xfer:={batchupload (pro,dir,baudrate,usecom);}
  2157.    doext ('U',pro,dir,'',baudrate,usecom);
  2158.    writeln (^M^M);
  2159.    if (xfer=0) or (xfer=1) then begin
  2160.    recv:=checkwork;
  2161.    writeln;
  2162.    clrscr;
  2163.    if fls>recv then writeln(^R'One or more files '^S'not received'^R'!');
  2164.    if fls<recv then writeln(^S'Extra'^R' files were received'^R'!');
  2165.    for cnt:=1 to fls do
  2166.    xtype:=checkdszlog (fnames[cnt]);
  2167.    for cnt:=1 to fls do begin
  2168.     if exist(xferdir+fnames[cnt]) then acceptfile(cnt);
  2169.     if zipcomment then begin
  2170.     addcomment (a.xmodemdir,fnames[cnt]);
  2171.     end;
  2172.    end;
  2173.    getextras;
  2174.    end;
  2175.    showhisstats;
  2176.    if answer='H' then laterdays;
  2177.    end;
  2178.  
  2179.   procedure clearbatch;
  2180.   var x:integer;
  2181.       kaos:text;
  2182.   begin
  2183.    assign (kaos,bat2);
  2184.    if exist (bat2) then erase (kaos);
  2185.    for x:=1 to numb do removebat (x);
  2186.   end;
  2187.  
  2188.   procedure killfrombatch;
  2189.   var num:integer;
  2190.   begin
  2191.    num:=getfilenum ('Erase from Batch Buffer');
  2192.    if num=0 then exit;
  2193.    removebat (num);
  2194.    writeln ('File removed from Batch Buffer.');
  2195.   end;
  2196.  
  2197.   procedure makeone(fn:string);
  2198.   var ff:file of protorec; fpro:protorec;
  2199.   begin
  2200.        assign(ff,fn); rewrite(ff);
  2201.        fpro.letter:='Z';
  2202.        fpro.desc:='External Zmodem';
  2203.        fpro.progname:='DSZ.COM';
  2204.        fpro.commfmt:=' port %1 speed %2 rz %3';
  2205.        write(ff,fpro);
  2206.        close(ff);
  2207.        writeln; writeln(^R'Protocol File "'^S+fn+^R'" created.');
  2208.   end;
  2209.  
  2210.   procedure doprotlist (pref,header:string);
  2211.   var ff:file of protorec; fpro:protorec; tf:lstr; crtime:boolean;
  2212.   begin
  2213.    if exist(textfiledir+pref+'.BBS') then printfile(textfiledir+pref+'.BBS') else
  2214.           begin
  2215.       writehdr(header); writeln;
  2216.           tf:=bbsdatadir+pref+'.CFG';  crtime:=true;
  2217.           assign(ff,tf); {$I-} reset(ff) {$I+};
  2218.           if ioresult <> 0 then makeone(tf);
  2219.           reset(ff);
  2220.                     while not eof(ff) do begin
  2221.                        read(ff,fpro);
  2222.                        tab(^S+'['+^R+fpro.letter+^S+'] '+^R+fpro.desc,39);
  2223.                        crtime:=not crtime;
  2224.                        if crtime then writeln;
  2225.                     end;
  2226.           close(ff);
  2227.           writeln; if not crtime then writeln;
  2228.           end;
  2229.   end;
  2230.  
  2231.   procedure listprotocols (t:integer);
  2232.   var bonzo:file of protorec; crtime: boolean;
  2233.   begin
  2234.    case t of
  2235.       0 : doprotlist('PROTS','Download Protocols');
  2236.       1 : doprotlist('PROTR','Upload Protocols');
  2237.       2 : doprotlist('PROTD','Batch Download Protocols');
  2238.       3 : doprotlist('PROTU','Batch Upload Protocols');
  2239.       end;
  2240.   end;
  2241.  
  2242.   procedure batchmenu;
  2243.   var i:integer;
  2244.   begin
  2245.    ansicls;
  2246.    bat2:=faqdir+'Xferlist.FAQ';
  2247.    writehdr ('FAQ Batch Transfer Menu');
  2248.    writeln (^R'You have filled '^S,numb,^R' spots in the Batch Buffer.');
  2249.    writeln (^R'Hit '^S'[L]'^R' to list the Buffer.');
  2250.    repeat
  2251.       i:=menu('Batch Transfer','BATCH','DULCKRQ?');
  2252.       case i of
  2253.        1:downbatch;
  2254.        2:upbatch;
  2255.        3:listbatch;
  2256.        4:clearbatch;
  2257.        5:killfrombatch;
  2258.        6:writeln ('There are ',checkwork,' files in the work directory.');
  2259.        8:begin
  2260. writeln ('C╔═════════════════════════════════════╗Hs');
  2261. writeln ('uC║ Batch Section                       ║Hs');
  2262. writeln ('uC╚═════════════════════════════════════╝HHC╔════s');
  2263. writeln ('u═════════════════════════════════╗HC║ [Cs');
  2264. writeln ('uClear Batch Queue               ║HC║ [Ds');
  2265. writeln ('uDownload Batch Queue            ║HC║ [s');
  2266. writeln ('uKKill File from Batch Queue      ║Hs');
  2267. writeln ('uC║ [LList Batch Queue                s');
  2268. writeln ('u║HC║ [QQuit                     s');
  2269. writeln ('u       ║HC║ [R# of Files in Batcs');
  2270. writeln ('uh Queue       ║HC║ [UUpload Batcs');
  2271. writeln ('uh                    ║HC║ [?Views');
  2272. writeln ('u This Menu                  ║HC╚═════════════════A');
  2273. writeln ('C════════════════════╝');
  2274. writeln;
  2275. pause;
  2276.            end;
  2277.           end;
  2278.     until hungupon or (i=7);
  2279.   end;
  2280.  
  2281. procedure fchangemenu;
  2282. begin
  2283. writeln ('C╔═════════════════════════════════════╗Hs');
  2284. writeln ('uC║ File Change Section                 ║Hs');
  2285. writeln ('uC╚═════════════════════════════════════╝HHC╔════s');
  2286. writeln ('u═════════════════════════════════╗HC║ [A]  s');
  2287. writeln ('uChange File Password           ║HC║ [Cs');
  2288. writeln ('u]  Comment File                   ║HC║ [s');
  2289. writeln ('uD]  Change Program Description     ║Hs');
  2290. writeln ('uC║ [E]  Change External Description    s');
  2291. writeln ('u║HC║ [F]  Change Filename         s');
  2292. writeln ('u       ║HC║ [N]  Change New File (s');
  2293. writeln ('uUnrated)      ║HC║ [P]  Change Pats');
  2294. writeln ('uh of File            ║HC║ [Q]  Quis');
  2295. writeln ('ut                           ║HC║ [R]  s');
  2296. writeln ('uChange Private File            ║HC║ [Ss');
  2297. writeln ('u]  Change Special Request Only    ║HC║ s');
  2298. writeln ('u[T]  Change Disk x of y             ║Hs');
  2299. writeln ('uC║ [U]  Change Uploader                s');
  2300. writeln ('u║HC║ [V]  Change File Cost        s');
  2301. writeln ('u       ║HC║ [?]  View This Menu   s');
  2302. writeln ('u              ║HC╚═══════════════════════════════A');
  2303. writeln ('C══════╝');
  2304. writeln;
  2305. pause;
  2306. end;
  2307.  
  2308. procedure newscanmenu;
  2309. begin
  2310. writeln ('C╔═════════════════════════════════════╗Hs');
  2311. writeln ('uC║ File Newscan Section                ║Hs');
  2312. writeln ('uC╚═════════════════════════════════════╝HHC╔════s');
  2313. writeln ('u═════════════════════════════════╗HC║ [C]  s');
  2314. writeln ('uChange Program Description     ║HC║ [Ds');
  2315. writeln ('u]  Rename File                    ║HC║ [s');
  2316. writeln ('uE]  Change Current Disk            ║Hs');
  2317. writeln ('uC║ [M]  Move File                      s');
  2318. writeln ('u║HC║ [P]  Change Total Disks      s');
  2319. writeln ('u       ║HC║ [Q]  Quit             s');
  2320. writeln ('u              ║HC║ [R]  View File s');
  2321. writeln ('u                     ║HC║ [T]  Dels');
  2322. writeln ('uete File                    ║HC║ [CRs');
  2323. writeln ('uContinue (Next Area)           ║HC║ [#s');
  2324. writeln ('u]  Rate File - # of Xfer Pts.     ║HC║ s');
  2325. writeln ('u[?]  View This Menu                 ║HA');
  2326. writeln ('C╚═════════════════════════════════════╝');
  2327. writeln;
  2328. pause;
  2329. end;
  2330.  
  2331. procedure sponsormenu;
  2332. begin
  2333. writeln ('C╔═════════════════════════════════════╗Hs');
  2334. writeln ('uC║ Transfer Sponsor Section            ║Hs');
  2335. writeln ('uC╚═════════════════════════════════════╝HHC╔═════s');
  2336. writeln ('u════════════════════════════════╗HC║ [A]  s');
  2337. writeln ('uAdd Resident File              ║HC║ [Cs');
  2338. writeln ('u]  Change File                    ║HC║ [s');
  2339. writeln ('uD]  Delete File                    ║Hs');
  2340. writeln ('uC║ [F]  Directory (DIR)                s');
  2341. writeln ('u║HC║ [G]  Log off BBS                   s');
  2342. writeln ('u ║HC║ [K]  Kill Area               s');
  2343. writeln ('u       ║HC║ [L]  List Users with Acs');
  2344. writeln ('ucess         ║HC║ [M]  Move File   s');
  2345. writeln ('u      ╔═════════════════════════════════════╗HCs');
  2346. writeln ('u║ [N]  Change New Files  ║ [Ss');
  2347. writeln ('u]  Sort Area                      ║HCs');
  2348. writeln ('u║ [O]  Re-Order Areas    ║ [Vs');
  2349. writeln ('u]  Rename All Files               ║HCs');
  2350. writeln ('u║ [Q]  Quit              ║ [Ws');
  2351. writeln ('u]  Add by Wildcard (Add Multiple) ║HCs');
  2352. writeln ('u║ [R]  Re-Configure File ║ [*s');
  2353. writeln ('u]  Change Active Area             ║HCs');
  2354. writeln ('u╚════════════════════════║ [?]  Views');
  2355. writeln ('u This Menu                 ║HC╚══════════════════A');
  2356. writeln ('C═══════════════════╝');
  2357. writeln;
  2358. pause;
  2359. end;
  2360.  
  2361. procedure xfermenu;
  2362. begin
  2363. writeln ('C╔═════════════════════════════════════╗Hs');
  2364. writeln ('uC║ Transfer Section                    ║Hs');
  2365. writeln ('uC╚═════════════════════════════════════╝HHC╔═════s');
  2366. writeln ('u════════════════════════════════╗HC║ [A]  s');
  2367. writeln ('uChange Active Area             ║HC║ [Bs');
  2368. writeln ('u]  Batch Section                  ║HC║ [s');
  2369. writeln ('uD]  Download File                  ║Hs');
  2370. writeln ('uC║ [E]  Request File           ╔════s');
  2371. writeln ('u═════════════════════════════════╗HC║ [Fs');
  2372. writeln ('u]  Configure File Listing ║ [T]  s');
  2373. writeln ('uType File                      ║HC║ [s');
  2374. writeln ('uG]  Generate File List     ║ [Us');
  2375. writeln ('u]  Upload File                    ║HCs');
  2376. writeln ('u║ [J]  Jump to Another Conf.  ║ [s');
  2377. writeln ('uV]  Newscan Current Area           ║Hs');
  2378. writeln ('uC║ [L]  List Files             s');
  2379. writeln ('u║ [W]  Send Mail to Sponsor           ');
  2380. writeln ('HC║ [N]  Newscan All Areas      s');
  2381. writeln ('u║ [X]  Extended Description Listing   ');
  2382. writeln ('HC║ [Q]  Quit                   s');
  2383. writeln ('u║ [Y]  Your Xfer Statistics           ');
  2384. writeln ('HC║ [R]  View File              s');
  2385. writeln ('u║ [Z]  Extract File                   ');
  2386. writeln ('HC║ [S]  Search for Text        s');
  2387. writeln ('u║ [%]  File Sponsor Section           ');
  2388. writeln ('HC╚═════════════════════════════║ [+s');
  2389. writeln ('u]  Add File to Batch              ║HC║ s');
  2390. writeln ('u[?]  View This Menu                 ║HA');
  2391. writeln ('C╚═════════════════════════════════════╝');
  2392. writeln;
  2393. pause;
  2394. end;
  2395.  
  2396. end.